# Buggy code
def fit_transform(self, X, y=None):
    """Fit all transformers, transform the data and concatenate results.

    Parameters
    ----------
    X : array-like or DataFrame of shape [n_samples, n_features]
        Input data, of which specified subsets are used to fit the
        transformers.

    y : array-like, shape (n_samples, ...), optional
        Targets for supervised learning.

    Returns
    -------
    X_t : array-like or sparse matrix, shape (n_samples, sum_n_components)
        hstack of results of transformers. sum_n_components is the
        sum of n_components (output dimension) over transformers. If
        any result is a sparse matrix, everything will be converted to
        sparse matrices.

    """
    self._validate_transformers()
    self._validate_column_callables(X)
    self._validate_remainder(X)

    result = self._fit_transform(X, y, _fit_transform_one)

    if not result:
        self._update_fitted_transformers([])
        # All transformers are None
        return np.zeros((X.shape[0], 0))

    Xs, transformers = zip(*result)

    # determine if concatenated output will be sparse or not
    if all(sparse.issparse(X) for X in Xs):
        self.sparse_output_ = True
    elif any(sparse.issparse(X) for X in Xs):
        nnz = sum(X.nnz if sparse.issparse(X) else X.size for X in Xs)
        total = sum(
            X.shape[0] * X.shape[1] if sparse.issparse(X) else X.size for X in Xs
        )
        density = nnz / total
        self.sparse_output_ = density < self.sparse_threshold
    else:
        self.sparse_output_ = False

    self._update_fitted_transformers(transformers)
    self._validate_output(Xs)

    return self._hstack(list(Xs))


# Traceback (AttributeError)
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
ColumnTransformer([('foobar', StandardScaler(), [0, 1, 2])]).fit([[1, 2, 3]])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/joel/repos/scikit-learn/sklearn/compose/_column_transformer.py", line 398, in fit
self.fit_transform(X, y=y)
File "/Users/joel/repos/scikit-learn/sklearn/compose/_column_transformer.py", line 422, in fit_transform
self._validate_remainder(X)
File "/Users/joel/repos/scikit-learn/sklearn/compose/_column_transformer.py", line 275, in _validate_remainder
n_columns = X.shape[1]
AttributeError: 'list' object has no attribute 'shape'

# Fixed code
def fit_transform(self, X, y=None):
    """Fit all transformers, transform the data and concatenate results.

    Parameters
    ----------
    X : array-like or DataFrame of shape [n_samples, n_features]
        Input data, of which specified subsets are used to fit the
        transformers.

    y : array-like, shape (n_samples, ...), optional
        Targets for supervised learning.

    Returns
    -------
    X_t : array-like or sparse matrix, shape (n_samples, sum_n_components)
        hstack of results of transformers. sum_n_components is the
        sum of n_components (output dimension) over transformers. If
        any result is a sparse matrix, everything will be converted to
        sparse matrices.

    """
    X = _check_X(X)
    self._validate_transformers()
    self._validate_column_callables(X)
    self._validate_remainder(X)

    result = self._fit_transform(X, y, _fit_transform_one)

    if not result:
        self._update_fitted_transformers([])
        # All transformers are None
        return np.zeros((X.shape[0], 0))

    Xs, transformers = zip(*result)

    # determine if concatenated output will be sparse or not
    if all(sparse.issparse(X) for X in Xs):
        self.sparse_output_ = True
    elif any(sparse.issparse(X) for X in Xs):
        nnz = sum(X.nnz if sparse.issparse(X) else X.size for X in Xs)
        total = sum(
            X.shape[0] * X.shape[1] if sparse.issparse(X) else X.size for X in Xs
        )
        density = nnz / total
        self.sparse_output_ = density < self.sparse_threshold
    else:
        self.sparse_output_ = False

    self._update_fitted_transformers(transformers)
    self._validate_output(Xs)

    return self._hstack(list(Xs))