pola-rs/polars · error · TypeError
Cannot pass a dictionary as a single positional argument.\nI
Error message
Cannot pass a dictionary as a single positional argument.\nIf you merely want the *keys*, use:\n • df.method(*your_dict.keys())\nIf you need the key value pairs, use one of:\n • unpack as keywords: df.method(**your_dict)\n • build expressions: df.method(expr.alias(k) for k, expr in your_dict.items())
What it means
polars methods such as select/with_columns accept *exprs and **named_exprs. A dict passed as the single positional argument would be silently iterated as its keys by Python, which is almost never intended, so _parse_inputs_as_iterable (parse/expr.py:244) detects a lone Mapping and raises this TypeError listing the three correct spellings.
Source
Thrown at py-polars/src/polars/_utils/parse/expr.py:244
def _parse_inputs_as_iterable(
inputs: tuple[Any, ...] | tuple[Iterable[Any]],
) -> Iterable[Any]:
if not inputs:
return []
# Ensures that the outermost element cannot be a Dictionary (as an iterable)
if len(inputs) == 1 and isinstance(inputs[0], Mapping):
msg = (
"Cannot pass a dictionary as a single positional argument.\n"
"If you merely want the *keys*, use:\n"
" • df.method(*your_dict.keys())\n"
"If you need the key value pairs, use one of:\n"
" • unpack as keywords: df.method(**your_dict)\n"
" • build expressions: df.method(expr.alias(k) for k, expr in your_dict.items())"
)
raise TypeError(msg)
# Treat elements of a single iterable as separate inputs
if len(inputs) == 1 and _is_iterable(inputs[0]):
return inputs[0]
return inputs
def _is_iterable(input: Any) -> bool:
return isinstance(input, Iterable) and not isinstance(
input, (str, bytes, pl.Series)
)
def _parse_named_inputs(
named_inputs: dict[str, IntoExpr], *, structify: bool = False
) -> Iterable[PyExpr]:
for name, input in named_inputs.items():View on GitHub (pinned to df599052da)
Solutions
- Unpack as keywords: df.with_columns(**expr_map)
- Build aliased expressions: df.select(expr.alias(name) for name, expr in expr_map.items())
- If only the keys are wanted: df.select(*expr_map.keys())
Example fix
# before
df.select({"a": pl.col("b")})
# after
df.select(pl.col("b").alias("a")) # or df.select(**{"a": pl.col("b")}) Defensive patterns
Strategy: validation
Validate before calling
from collections.abc import Mapping
if len(inputs) == 1 and isinstance(inputs[0], Mapping):
raise TypeError("dict must be unpacked: use **expr_map or aliased expressions")
df.select(*inputs) Type guard
from collections.abc import Mapping
def is_bare_dict_arg(args: tuple) -> bool:
return len(args) == 1 and isinstance(args[0], Mapping) Prevention
- Unpack mapping kwargs with ** instead of passing the dict positionally
- Build aliased expressions via a generator when renaming
- Lint for f(**d) vs f(d) in code that forwards expression maps
When it happens
Trigger: df.select({'a': pl.col('b')}); df.with_columns({'x': pl.col('a') + 1}); dynamically built expr maps forwarded as f(dict) instead of f(**dict).
Common situations: Refactoring dict-based configuration into select; copying pandas assign({...}) style; helper code that forwards a kwargs dict positionally.
Related errors
- cannot turn {qualified_type_name(input)!r} into selector
- cannot select columns using key of type {qualified_type_name
- cannot select rows using key of type {qualified_type_name(ke
- cannot treat Series of type {s.dtype} as indices
- only 1D NumPy arrays can be treated as indices
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/0d04e1e6ba5621a3.
Report an issue: GitHub.