pandas-dev/pandas · error · TypeError
func is expected but received {} in **kwargs.
Error message
func is expected but received {} in **kwargs. What it means
Raised by validate_func_kwargs (apply.py:2313) as a TypeError when, during named-aggregation parsing, one of the kwargs values is neither a string nor a callable. Named-aggregation kwargs must be either a (column, aggfunc) tuple or a NamedAgg; if pandas ends up validating a value that is some other type (e.g. an int or a bare tuple it tries to read as func), it reports which type it received via the {} placeholder.
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 71959b8cb9)
Solutions
- Make each kwarg value either a string (e.g. 'sum') or a callable (e.g. np.mean), wrapped in the (column, func) tuple form: df.agg(out=('col','sum')).
- Use pandas.NamedAgg for clarity: df.agg(out=pd.NamedAgg(column='col', aggfunc='sum')).
- Validate kwargs types before calling agg: assert all(callable(v) or isinstance(v, str) for v in your_funcs.values()).
Example fix
// before
df.agg(out=('col', 5)) # 5 is not a valid aggfunc
// after
df.agg(out=('col', 'sum')) Defensive patterns
Strategy: type-guard
Validate before calling
for name, v in kwargs.items():
if not (isinstance(v, str) or callable(v)):
raise TypeError(f'kwarg {name!r} value {v!r} is not a str or callable') Type guard
def named_agg_kwargs_valid(kwargs: dict) -> bool:
return all(isinstance(v, str) or callable(v) for v in kwargs.values()) Try / catch
try:
df.agg(**kwargs)
except TypeError as e:
if 'func is expected' in str(e):
# coerce or drop offending kwargs
cleaned = {k: v for k, v in kwargs.items() if isinstance(v, str) or callable(v)}
df.agg(**cleaned)
else:
raise Prevention
- Always wrap named-agg values as (column, func) tuples or NamedAgg objects.
- Validate dynamic kwargs before passing them to agg.
When it happens
Trigger: df.agg(out=(5,)) or any named-agg kwarg whose value (after tuple-unpacking) is not str/callable. Triggered in validate_func_kwargs at apply.py:2311-2313 when col_func fails isinstance(col_func, str) and not callable(col_func).
Common situations: Passing df.agg(name=42) by mistake; passing a dict-of-params instead of (column, func); mixing API styles so a value lands where pandas expects an aggfunc; misformatted tuples like (col,) missing the func element.
Related errors
- Must provide 'func' or tuples of '(column, aggfunc).
- Must provide 'func' or named aggregation **kwargs.
- cannot combine transform and aggregation operations
- cannot perform both aggregation and transformation operation
- nested renamer is not supported
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/71c7074f89e28725.
Report an issue: GitHub.