pola-rs/polars · error · TypeError
invalid input for `col` Expected `str` or `DataType`, got {
Error message
invalid input for `col`
Expected `str` or `DataType`, got {type(name).__name__!r}. What it means
When pl.col is called with extra positional arguments, the first argument must be a str (column name) or a Polars dtype so a name- or dtype-based selector can be built. Any other first argument alongside more_names raises this TypeError before a selector is created. Python type objects like int are only accepted in the single-argument form.
Source
Thrown at py-polars/src/polars/functions/col.py:68
"""Create one or more column expressions representing column(s) in a DataFrame."""
dtypes: list[PolarsDataType]
if more_names:
if isinstance(name, str):
names_str = [name]
names_str.extend(more_names) # type: ignore[arg-type]
return pl.Selector._by_name(
names_str, strict=True, expand_patterns=True
).as_expr()
elif is_polars_dtype(name):
dtypes = [name]
dtypes.extend(more_names) # type: ignore[arg-type]
return pl.Selector._by_dtype(dtypes).as_expr() # type: ignore[arg-type]
else:
msg = (
"invalid input for `col`"
f"\n\nExpected `str` or `DataType`, got {type(name).__name__!r}."
)
raise TypeError(msg)
if isinstance(name, str):
return wrap_expr(plr.col(name))
elif is_polars_dtype(name):
dtypes = _polars_dtype_match(name)
return pl.Selector._by_dtype(dtypes).as_expr() # type: ignore[arg-type]
elif isinstance(name, type):
dtypes = _python_dtype_match(name)
return pl.Selector._by_dtype(dtypes).as_expr() # type: ignore[arg-type]
elif isinstance(name, Iterable):
names = list(name)
if not names:
return pl.Selector._by_name(
names=names, # type: ignore[arg-type]
strict=True,
expand_patterns=True,
).as_expr()
View on GitHub (pinned to df599052da)
Solutions
- Make the first argument a column-name str or a real Polars dtype (pl.Int64, not 'int64')
- Normalize dynamic lists before splatting: names = [n for n in names if isinstance(n, str)]
- For Python type objects drop the extra args: pl.col(int) alone works
Example fix
# before pl.col(*cols) # cols[0] is an int or None # after pl.col(*[str(c) for c in cols]) # or select by dtype with real dtype objects: pl.col(pl.Int64, pl.Float64)
Defensive patterns
Strategy: type-guard
Validate before calling
names = [n for n in candidate_names if isinstance(n, str)]
if not names:
raise ValueError('no valid column names supplied')
expr = pl.col(*names) Type guard
def is_col_first_arg(x: object) -> bool:
return isinstance(x, str) or hasattr(x, '__pl.TimeUnit__') or isinstance(x, type) Prevention
- Normalize dynamic name lists to str before splatting into pl.col
- Use real dtype objects (pl.Int64), never dtype strings, alongside more_names
- Keep a single helper that validates and builds column selectors
When it happens
Trigger: pl.col(None, 'a', 'b'); pl.col(123, 'x'); splatting a dynamic list where the first element is not a str: pl.col(*names) with names[0] an int; passing the string 'int64' with more names (strings are treated as column names, not dtypes).
Common situations: Programmatic column selection where the first element came from untrusted or empty data; mixing dtype classes (pl.Int64) with dtype strings; kwargs/splat forwarding helpers.
Related errors
- invalid input for `col` Expected iterable of type `str` or
- cannot select columns using key of type {qualified_type_name
- cannot turn {qualified_type_name(input)!r} into selector
- cannot turn {qualified_type_name(i)!r} into selector
- "pad_start" expects a `str`, given a {qualified_type_name(fi
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/a61b1602a222ecee.
Report an issue: GitHub.