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

  1. Use expressions: .agg(pl.col('b').sum(), pl.col('c').max())
  2. Use keyword syntax with expression values: .agg(b_sum=pl.col('b').sum())
  3. Unpack a dict of expressions: .agg(**{'b': pl.col('b').sum()})
  4. 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

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


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/a210d92646e98deb. Report an issue: GitHub.