pandas-dev/pandas · error · ValueError

Transform function failed

Error message

Transform function failed

What it means

Raised inside `Apply.transform` when the user-supplied transform function raises a non-TypeError exception while executing on a str-or-callable path. The original exception is chained via `from err`. This indicates the function ran but failed (e.g. arithmetic error, missing attribute) rather than being structurally invalid.

Source

Thrown at pandas/core/apply.py:393

                )
            # Convert func equivalent dict
            if is_series:
                func = {com.get_callable_name(v) or v: v for v in func}
            else:
                func = dict.fromkeys(obj, func)

        if is_dict_like(func):
            func = cast("AggFuncTypeDict", func)
            return self.transform_dict_like(func)

        # func is either str or callable
        func = cast("AggFuncTypeBase", func)
        try:
            result = self.transform_str_or_callable(func)
        except TypeError:
            raise
        except Exception as err:
            raise ValueError("Transform function failed") from err

        # Functions that transform may return empty Series/DataFrame
        # when the dtype is not appropriate
        if (
            isinstance(result, (ABCSeries, ABCDataFrame))
            and result.empty
            and not obj.empty
        ):
            raise ValueError("Transform function failed")
        if not isinstance(result, (ABCSeries, ABCDataFrame)) or not result.index.equals(
            obj.index
        ):
            raise ValueError("Function did not transform")

        return result

    def transform_dict_like(self, func) -> DataFrame:
        """

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Inspect the chained exception (`__cause__`) — the original traceback shows the real failure; fix that root cause.
  2. Test the function on a single column/Series first via `func(df['col'])` to reproduce the underlying error directly.
  3. Add dtype/column pre-checks in your transform function and raise a more informative error.

Example fix

# before
df.transform(lambda s: np.log(s))  # fails on object dtypes
# after
num = df.select_dtypes(include='number')
num.transform(lambda s: np.log(s))
Defensive patterns

Strategy: try-catch

Validate before calling

def test_func_on_series(func, s):
    """Smoke-test a transform func on one column before applying frame-wide."""
    try:
        out = func(s.copy())
        return out is not None
    except Exception:
        return False

if test_func_on_series(my_func, df[df.columns[0]]):
    df.transform(my_func)

Try / catch

try:
    df.transform(my_func)
except ValueError as e:
    if 'Transform function failed' in str(e) and e.__cause__ is not None:
        raise RuntimeError(f'underlying error: {e.__cause__!r}') from e.__cause__
    raise

Prevention

When it happens

Trigger: Calling `df.transform(func)` where `func` raises an exception internally (e.g. division by zero, KeyError on a column, numpy ValueError on bad dtype) but not a TypeError. The wrapper catches Exception, rewraps as ValueError('Transform function failed').

Common situations: Passing a function that assumes a dtype the column doesn't have (e.g. `np.log` on object column); functions that reference missing columns; chained operations where an intermediate step fails; debugging confusion because the original traceback is chained but the top message is generic.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/efdcf192cd8e04ee. Report an issue: GitHub.