pandas-dev/pandas · error · TypeError
Must provide 'func' or tuples of '(column, aggfunc).
Error message
Must provide 'func' or tuples of '(column, aggfunc).
What it means
Raised by reconstruct_func (apply.py:1946) as a TypeError when func is None and the kwargs do not form a valid relabeling/named-aggregation spec. reconstruct_func accepts either a real func (string/callable/list/dict) or kwargs that look like named aggregation (column, aggfunc) tuples / NamedAgg objects; if neither is present the user has effectively passed nothing actionable.
Source
Thrown at pandas/core/apply.py:1946
relabeling = func is None and (
is_multi_agg_with_relabel(**kwargs)
or any(isinstance(v, NamedAgg) for v in kwargs.values())
)
columns: tuple[str, ...] | None = None
order: npt.NDArray[np.intp] | None = None
if not relabeling:
if isinstance(func, list) and len(func) > len(set(func)):
# GH 28426 will raise error if duplicated function names are used and
# there is no reassigned name
raise SpecificationError(
"Function names must be unique if there is no new column names assigned"
)
if func is None:
# nicer error message
raise TypeError("Must provide 'func' or tuples of '(column, aggfunc).")
if relabeling:
normalization_needed = False
# error: Incompatible types in assignment (expression has type
# "MutableMapping[Hashable, list[Callable[..., Any] | str]]", variable has type
# "Callable[..., Any] | str | list[Callable[..., Any] | str] |
# MutableMapping[Hashable, Callable[..., Any] | str | list[Callable[..., Any] |
# str]] | None")
converted_kwargs = {}
for key, val in kwargs.items():
if isinstance(val, NamedAgg):
column = val.column
aggfunc = val.aggfunc
if val.args or val.kwargs:
aggfunc = lambda x, func=aggfunc, a=val.args, kw=val.kwargs: func(
x, *a, **kw
)
else:View on GitHub (pinned to 71959b8cb9)
Solutions
- Pass a real func or named-aggregation kwargs: df.agg('sum'), df.agg({'a':'sum'}), or df.agg(out=('a','sum')).
- If the spec is built dynamically, guard against empty/None before calling agg and skip the call or supply a default.
- For named aggregation use the tuple form df.agg(new_name=(column, func)) or NamedAgg(column=..., aggfunc=...).
Example fix
// before
spec = None # accidentally empty
df.agg(spec)
// after
df.agg('sum')
// or named
import pandas as pd
df.agg(total=pd.NamedAgg(column='a', aggfunc='sum')) Defensive patterns
Strategy: validation
Validate before calling
if func is None and not kwargs:
raise TypeError("agg requires a func or named-aggregation kwargs") Type guard
def agg_has_spec(func, kwargs: dict) -> bool:
return func is not None or bool(kwargs) Try / catch
try:
df.agg(func, **kwargs)
except TypeError as e:
if "Must provide 'func'" in str(e):
df.agg('sum') # sensible default
else:
raise Prevention
- Never call agg() with no arguments.
- When building specs dynamically, fall back to a default like 'sum' if the spec resolves to None/empty.
When it happens
Trigger: df.agg(None), df.agg(), or df.groupby('g').agg() with no positional func and no kwargs matching the named-aggregation shape. Triggered at apply.py:1944-1946 when func is None and the relabeling check at apply.py:1929-1932 returned False.
Common situations: Building the agg spec dynamically and ending up with an empty/None value; typo in the kwarg (e.g. df.agg(col=sum) without the tuple form); refactoring that stripped the positional arg; calling agg with a variable that evaluated to None.
Related errors
- Must provide 'func' or named aggregation **kwargs.
- func is expected but received {} in **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/84844015fcad1abe.
Report an issue: GitHub.