pola-rs/polars · error · TypeError
invalid type for `on_columns` argument: {qualified_type_name
Error message
invalid type for `on_columns` argument: {qualified_type_name(on_columns)!r} What it means
In LazyFrame.pivot, `on_columns` supplies the values to pivot on (an iterable of values, a pl.Series, or a pl.DataFrame). A bare `str` is explicitly rejected with TypeError because a string is itself a Sequence and would otherwise be silently iterated character-by-character, producing a wrong pivot.
Source
Thrown at py-polars/src/polars/lazyframe/frame.py:8695
version="0.20.5",
)
agg = agg.len()
else:
msg = f"invalid input for `aggregate_function` argument: {aggregate_function!r}"
raise ValueError(msg)
elif aggregate_function is None:
agg = agg.item(allow_empty=True)
else:
agg = aggregate_function
on_cols: pl.DataFrame
if isinstance(on_columns, pl.DataFrame):
on_cols = on_columns
elif isinstance(on_columns, pl.Series):
on_cols = on_columns.to_frame()
elif isinstance(on_columns, str):
msg = f"invalid type for `on_columns` argument: {qualified_type_name(on_columns)!r}"
raise TypeError(msg)
else:
on_cols = pl.Series(values=on_columns).to_frame()
return self._from_pyldf(
self._ldf.pivot(
on=on_selector._pyselector,
on_columns=on_cols._df,
index=index_selector._pyselector,
values=values_selector._pyselector,
agg=agg._pyexpr,
maintain_order=maintain_order,
separator=separator,
column_naming=column_naming,
)
)
def unpivot(
self,View on GitHub (pinned to df599052da)
Solutions
- Wrap the string in a list: on_columns=['a']
- Pass a pl.Series or pl.DataFrame holding the pivot values: on_columns=pl.Series(['a','b'])
- If you meant a column of the frame to pivot on, pass it to `on`, not `on_columns`
Example fix
// before
lf.pivot('subject', on_columns='maths', values=cs.starts_with('test'))
// after
lf.pivot('subject', on_columns=['maths'], values=cs.starts_with('test')) Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Sequence
if isinstance(on_columns, str):
on_columns = [on_columns] # or raise your own error with context Type guard
import polars as pl
from collections.abc import Sequence
def is_valid_on_columns(x) -> bool:
return isinstance(x, (pl.Series, pl.DataFrame)) or (
isinstance(x, Sequence) and not isinstance(x, str)
) Prevention
- Never pass a bare str where polars accepts Sequence[Any]; strings are sequences and polars guards against char-iteration
- Remember the split: `on` selects the frame column, `on_columns` provides the literal pivot values
When it happens
Trigger: Calling lf.pivot('col', on_columns='a', ...) with a single string instead of a list; passing a column-name string to `on_columns` (the new-style value parameter) instead of `on` (the column selector).
Common situations: Migrating from older pivot signatures where string column names were the norm; confusion between `on` (which column to pivot) and `on_columns` (which values appear as new columns); passing a single value without wrapping it.
Related errors
- `pivot` needs either `index or `values` needs to be specifie
- invalid input for `aggregate_function` argument: {aggregate_
- negative stop is not supported for lazy slices
- negative stride is not supported in conjunction with start+s
- the given slice {s!r} is not supported by lazy computation\n
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/5f3cd4c8477456cd.
Report an issue: GitHub.