pandas-dev/pandas · error · TypeError

func is expected but received

Error message

func is expected but received {} in **kwargs.

What it means

TypeError raised in validate_func_kwargs when named-aggregation kwargs contain a value that is neither a string nor callable. Named aggregation values must be aggregations (e.g. 'sum', np.mean, a lambda); anything else is treated as a misuse.

Solutions

  1. Make each kwarg value a function name or callable: df.agg(a='sum').
  2. For column-specific aggregation use NamedAgg: df.agg(result=NamedAgg(column='mycol', aggfunc='sum')).
  3. If the value is a list, ensure every element is callable or a string name.

Example fix

# before
df.agg(a=1)
# after
df.agg(a='sum')
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_named_agg_kwargs(kwargs):
    bad = {k: type(v).__name__ for k, v in kwargs.items() if not (isinstance(v, str) or callable(v))}
    if bad:
        raise TypeError(f'non-callable agg values: {bad}')
    return kwargs

df.agg(**validate_named_agg_kwargs(kwargs))

Type guard

def is_valid_agg_value(v) -> bool:
    return isinstance(v, str) or callable(v)

Try / catch

try:
    df.agg(**kwargs)
except TypeError as e:
    if 'func is expected' in str(e):
        kwargs = {k: 'sum' for k in kwargs}  # or surface to user
        df.agg(**kwargs)
    else:
        raise

Prevention

When it happens

Trigger: df.agg(a=1); df.agg(x=[1, 2]); df.groupby('k').agg(result=5); passing a column name where the function should go.

Common situations: Confusing the column and function positions, e.g. df.agg(mycol='target_column') intending to select a column rather than name an aggregation.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/71c7074f89e28725. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/apply.py:2313

    Returns
    -------
    columns : List[str]
        List of user-provided keys.
    func : List[Union[str, callable[...,Any]]]
        List of user-provided aggfuncs

    Examples
    --------
    >>> validate_func_kwargs({"one": "min", "two": "max"})
    (['one', 'two'], ['min', 'max'])
    """
    tuple_given_message = "func is expected but received {} in **kwargs."
    columns = list(kwargs)
    func = []
    for col_func in kwargs.values():
        if not (isinstance(col_func, str) or callable(col_func)):
            raise TypeError(tuple_given_message.format(type(col_func).__name__))
        func.append(col_func)
    if not columns:
        no_arg_message = "Must provide 'func' or named aggregation **kwargs."
        raise TypeError(no_arg_message)
    return columns, func


def include_axis(op_name: Literal["agg", "apply"], colg: Series | DataFrame) -> bool:
    return isinstance(colg, ABCDataFrame) or (
        isinstance(colg, ABCSeries) and op_name == "agg"
    )

View on GitHub (pinned to 3b7651241d)