pandas-dev/pandas · error · ValueError

invalid value for result_type, must be one of {None, 'reduce

Error message

invalid value for result_type, must be one of {None, 'reduce', 'broadcast', 'expand'}

What it means

Raised by the Apply constructor when the `result_type` argument is not one of the four permitted values. `result_type` controls how `DataFrame.apply` shapes row-wise results, and only a fixed enum is meaningful. Any other string (including typos like 'Reduce' or 'broadcasted') is rejected at construction time. This guards downstream shape-handling code from undefined behavior.

Source

Thrown at pandas/core/apply.py:293

        engine: str = "python",
        engine_kwargs: dict[str, bool] | None = None,
        args,
        kwargs,
    ) -> None:
        self.obj = obj
        self.raw = raw

        assert by_row is False or by_row in ["compat", "_compat"]
        self.by_row = by_row

        self.args = args or ()
        self.kwargs = kwargs or {}

        self.engine = engine
        self.engine_kwargs = {} if engine_kwargs is None else engine_kwargs

        if result_type not in [None, "reduce", "broadcast", "expand"]:
            raise ValueError(
                "invalid value for result_type, must be one "
                "of {None, 'reduce', 'broadcast', 'expand'}"
            )

        self.result_type = result_type

        self.func = func

    @abc.abstractmethod
    def apply(self) -> DataFrame | Series:
        pass

    @abc.abstractmethod
    def agg_or_apply_list_like(
        self, op_name: Literal["agg", "apply"]
    ) -> DataFrame | Series:
        pass

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use one of the four accepted values exactly as written: None, 'reduce', 'broadcast', or 'expand' (case-sensitive, lowercase).
  2. If the value comes from user/config input, validate it against the allowed set before passing to `apply`.
  3. Omit `result_type` entirely if you want the default shape inference behavior.

Example fix

# before
df.apply(split_col, axis=1, result_type='broadcasted')
# after
df.apply(split_col, axis=1, result_type='broadcast')
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
_VALID_RESULT_TYPES = {None, 'reduce', 'broadcast', 'expand'}

def safe_apply(df, func, result_type=None, **kw):
    if result_type not in _VALID_RESULT_TYPES:
        raise ValueError(f"result_type must be one of {_VALID_RESULT_TYPES}, got {result_type!r}")
    return df.apply(func, result_type=result_type, **kw)

Type guard

def is_valid_result_type(v) -> bool:
    return v in {None, 'reduce', 'broadcast', 'expand'}

Try / catch

try:
    df.apply(f, result_type=rt)
except ValueError as e:
    if 'invalid value for result_type' in str(e):
        # log / fall back to default
        df.apply(f)
    else:
        raise

Prevention

When it happens

Trigger: Calling `df.apply(func, axis=1, result_type='reduce')` (or 'broadcast'/'expand') with a misspelled value, e.g. `result_type='broadcasted'`, `result_type='Reduce'`, or `result_type='wide'`. Also triggered by passing an arbitrary string variable that was not validated before being forwarded into `apply`.

Common situations: Developers passing `result_type` from a config dict or CLI argument without validation; copy-paste from docs with a typo; version upgrades where the set of accepted values was tightened and previously-tolerated values now raise.

Related errors


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