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

  1. Make the first argument a column-name str or a real Polars dtype (pl.Int64, not 'int64')
  2. Normalize dynamic lists before splatting: names = [n for n in names if isinstance(n, str)]
  3. 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

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


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