pola-rs/polars · error · TypeError
specifying aggregations as a dictionary is not supported\n\n
Error message
specifying aggregations as a dictionary is not supported\n\nTry unpacking the dictionary to take advantage of the keyword syntax of the `agg` method.
What it means
GroupBy.agg does not accept a single dict of name->aggregation (the old/pandas-style API). If the first positional argument is a dict, TypeError is raised with a hint to unpack it into keyword arguments; note the dict VALUES must be polars expressions, not strings like 'sum'.
Source
Thrown at py-polars/src/polars/lazyframe/group_by.py:193
... ).collect() # doctest: +IGNORE_RESULT
shape: (3, 3)
┌─────┬───────┬────────────────┐
│ a ┆ b_sum ┆ c_mean_squared │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ f64 │
╞═════╪═══════╪════════════════╡
│ a ┆ 2 ┆ 17.0 │
│ c ┆ 3 ┆ 1.0 │
│ b ┆ 5 ┆ 10.0 │
└─────┴───────┴────────────────┘
"""
if aggs and isinstance(aggs[0], dict):
msg = (
"specifying aggregations as a dictionary is not supported"
"\n\nTry unpacking the dictionary to take advantage of the keyword syntax"
" of the `agg` method."
)
raise TypeError(msg)
pyexprs = parse_into_list_of_expressions(*aggs, **named_aggs)
return wrap_ldf(self.lgb.agg(pyexprs))
def map_groups(
self,
function: Callable[[DataFrame], DataFrame],
schema: SchemaDict | None,
) -> LazyFrame:
"""
Apply a custom/user-defined function (UDF) over the groups as a new DataFrame.
.. warning::
This method is much slower than the native expressions API.
Only use it if you cannot implement your logic otherwise.
Using this is considered an anti-pattern as it will be very slow because:
View on GitHub (pinned to df599052da)
Solutions
- Use expressions: .agg(pl.col('b').sum(), pl.col('c').max())
- Use keyword syntax with expression values: .agg(b_sum=pl.col('b').sum())
- Unpack a dict of expressions: .agg(**{'b': pl.col('b').sum()})
- For many columns: .agg(pl.col(cols).sum().name.prefix('sum_'))
Example fix
// before
lf.group_by('a').agg({'b': 'sum', 'c': 'max'})
// after
lf.group_by('a').agg(pl.col('b').sum(), pl.col('c').max()) Defensive patterns
Strategy: type-guard
Validate before calling
if aggs and isinstance(aggs[0], dict):
aggs = [expr for name, expr in aggs[0].items()] # values must already be Exprs
# then .agg(*aggs) Type guard
def is_dict_agg(args) -> bool:
return bool(args) and isinstance(args[0], dict) Prevention
- Always aggregate with pl.col(...).<method>() expressions in polars; string specs like 'sum' are pandas-only
- Keyword form .agg(name=expr) gives named output columns directly
When it happens
Trigger: lf.group_by('a').agg({'b': 'sum'}); .agg({'b': 'sum', 'c': 'max'}) translated from pandas; LLM/snippet-generated dict aggregations.
Common situations: Migrating pandas workflows or pre-0.19 polars code; copy-pasted examples using dict syntax.
Related errors
- invalid `return_type`; found {return_type!r}, expected one o
- Expected Polars expression or object convertible to one, got
- cannot call `map_groups` when filtering groups with `having`
- cannot call `map_groups` when grouping by named expressions
- `strict` cannot be used with `how='horizontal_extend'`
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/a210d92646e98deb.
Report an issue: GitHub.