# Buggy code
def fit(self, X, Y, **fit_params):
    """Fit the model to data matrix X and targets Y.

    Parameters
    ----------
    X : {array-like, sparse matrix} of shape (n_samples, n_features)
        The input data.
    Y : array-like of shape (n_samples, n_classes)
        The target values.
    **fit_params : dict of string -> object
        Parameters passed to the `fit` method of each step.

    Returns
    -------
    self : object
    """
    X, Y = self._validate_data(X, Y, multi_output=True, accept_sparse=True)

    random_state = check_random_state(self.random_state)
    check_array(X, accept_sparse=True)
    self.order_ = self.order
    if self.order_ is None:
        self.order_ = np.array(range(Y.shape[1]))
    elif isinstance(self.order_, str):
        if self.order_ == "random":
            self.order_ = random_state.permutation(Y.shape[1])
    elif sorted(self.order_) != list(range(Y.shape[1])):
        raise ValueError("invalid order")

    self.estimators_ = [clone(self.base_estimator) for _ in range(Y.shape[1])]

    if self.cv is None:
        Y_pred_chain = Y[:, self.order_]
        if sp.issparse(X):
            X_aug = sp.hstack((X, Y_pred_chain), format="lil")
            X_aug = X_aug.tocsr()
        else:
            X_aug = np.hstack((X, Y_pred_chain))

    elif sp.issparse(X):
        Y_pred_chain = sp.lil_matrix((X.shape[0], Y.shape[1]))
        X_aug = sp.hstack((X, Y_pred_chain), format="lil")

    else:
        Y_pred_chain = np.zeros((X.shape[0], Y.shape[1]))
        X_aug = np.hstack((X, Y_pred_chain))

    del Y_pred_chain

    for chain_idx, estimator in enumerate(self.estimators_):
        y = Y[:, self.order_[chain_idx]]
        estimator.fit(X_aug[:, : (X.shape[1] + chain_idx)], y, **fit_params)
        if self.cv is not None and chain_idx < len(self.estimators_) - 1:
            col_idx = X.shape[1] + chain_idx
            cv_result = cross_val_predict(
                self.base_estimator, X_aug[:, :col_idx], y=y, cv=self.cv
            )
            if sp.issparse(X_aug):
                X_aug[:, col_idx] = np.expand_dims(cv_result, 1)
            else:
                X_aug[:, col_idx] = cv_result

    return self


# Traceback (IndexError)
Traceback (most recent call last):
File "tmp.py", line 11, in <module>
chain.predict(X)
File "/Users/augustbrocchini/anaconda3/lib/python3.6/site-packages/sklearn/multioutput.py", line 528, in predict
inv_order[self.order_] = np.arange(len(self.order_))
IndexError: too many indices for array

# Fixed code
def fit(self, X, Y, **fit_params):
    """Fit the model to data matrix X and targets Y.

    Parameters
    ----------
    X : {array-like, sparse matrix} of shape (n_samples, n_features)
        The input data.
    Y : array-like of shape (n_samples, n_classes)
        The target values.
    **fit_params : dict of string -> object
        Parameters passed to the `fit` method of each step.

    Returns
    -------
    self : object
    """
    X, Y = self._validate_data(X, Y, multi_output=True, accept_sparse=True)

    random_state = check_random_state(self.random_state)
    check_array(X, accept_sparse=True)
    self.order_ = self.order
    if isinstance(self.order_, tuple):
        self.order_ = np.array(self.order_)

    if self.order_ is None:
        self.order_ = np.array(range(Y.shape[1]))
    elif isinstance(self.order_, str):
        if self.order_ == "random":
            self.order_ = random_state.permutation(Y.shape[1])
    elif sorted(self.order_) != list(range(Y.shape[1])):
        raise ValueError("invalid order")

    self.estimators_ = [clone(self.base_estimator) for _ in range(Y.shape[1])]

    if self.cv is None:
        Y_pred_chain = Y[:, self.order_]
        if sp.issparse(X):
            X_aug = sp.hstack((X, Y_pred_chain), format="lil")
            X_aug = X_aug.tocsr()
        else:
            X_aug = np.hstack((X, Y_pred_chain))

    elif sp.issparse(X):
        Y_pred_chain = sp.lil_matrix((X.shape[0], Y.shape[1]))
        X_aug = sp.hstack((X, Y_pred_chain), format="lil")

    else:
        Y_pred_chain = np.zeros((X.shape[0], Y.shape[1]))
        X_aug = np.hstack((X, Y_pred_chain))

    del Y_pred_chain

    for chain_idx, estimator in enumerate(self.estimators_):
        y = Y[:, self.order_[chain_idx]]
        estimator.fit(X_aug[:, : (X.shape[1] + chain_idx)], y, **fit_params)
        if self.cv is not None and chain_idx < len(self.estimators_) - 1:
            col_idx = X.shape[1] + chain_idx
            cv_result = cross_val_predict(
                self.base_estimator, X_aug[:, :col_idx], y=y, cv=self.cv
            )
            if sp.issparse(X_aug):
                X_aug[:, col_idx] = np.expand_dims(cv_result, 1)
            else:
                X_aug[:, col_idx] = cv_result

    return self