pola-rs/polars · error
invalid dtype: {tp!r}
Error message
invalid dtype: {tp!r} What it means
Thrown inside cs.by_dtype (py-polars/src/polars/selectors.py:1098) when a TOP-LEVEL argument is not a DataType, not a Python class, and not a Collection. by_dtype(*dtypes) flattens collections and validates each item; an outer item that is itself invalid (an int, a string, None, a DataFrame column object, etc.) hits this else-branch and raises TypeError.
Source
Thrown at py-polars/src/polars/selectors.py:1098
│ str ┆ i64 │
╞═══════╪══════════╡
│ bar ┆ 5000555 │
│ foo ┆ -3265500 │
└───────┴──────────┘
"""
all_dtypes: builtins.list[PolarsDataType | PythonDataType] = []
for tp in dtypes:
if is_polars_dtype(tp) or isinstance(tp, type):
all_dtypes.append(tp)
elif isinstance(tp, Collection):
for t in tp:
if not (is_polars_dtype(t) or isinstance(t, type)):
msg = f"invalid dtype: {t!r}"
raise TypeError(msg)
all_dtypes.append(t)
else:
msg = f"invalid dtype: {tp!r}"
raise TypeError(msg)
return Selector._by_dtype(all_dtypes)
def by_index(
*indices: int | range | Sequence[int | range], require_all: bool = True
) -> Selector:
"""
Select all columns matching the given indices (or range objects).
Parameters
----------
*indices
One or more column indices (or range objects).
Negative indexing is supported.
require_all
By default, all specified indices must be valid; if any index is out of bounds,
an error is raised. If set to `False`, out-of-bounds indices are ignoredView on GitHub (pinned to df599052da)
Solutions
- Pass Polars dtypes or Python classes: cs.by_dtype(pl.Int64) or cs.by_dtype(int, float)
- Guard optional config: only call cs.by_dtype(*dtypes) when all items are dtypes/classes; skip or default when the list is empty
- Convert string dtype names to pl.* dtypes before the call (see by_dtype docs for the accepted forms)
Example fix
# before
sel = cs.by_dtype("float") # str is not a dtype
# after
sel = cs.by_dtype(pl.Float64)
# or
sel = cs.by_dtype(float) Defensive patterns
Strategy: type-guard
Validate before calling
import polars as pl
def to_dtype_args(items):
out = []
for it in items:
if pl.api.is_polars_dtype(it) or isinstance(it, type):
out.append(it)
elif isinstance(it, str):
out.append(getattr(pl, it)) # 'Int64' -> pl.Int64
else:
raise TypeError(f"invalid dtype: {it!r}")
return out Type guard
def is_by_dtype_arg(item: object) -> bool:
import polars as pl
return pl.api.is_polars_dtype(item) or isinstance(item, type) Try / catch
try:
sel = cs.by_dtype(*args)
except TypeError as e:
if "invalid dtype" in str(e):
# fall back to per-item validation with a clearer message
for a in args:
assert pl.api.is_polars_dtype(a) or isinstance(a, type), f"bad dtype {a!r}"
raise Prevention
- Validate optional dtype lists before calling by_dtype; never pass unvalidated config values
- Remember both pl.Int64 and the Python class int are accepted; strings never are
When it happens
Trigger: cs.by_dtype(5), cs.by_dtype("float"), cs.by_dtype(None), or cs.by_dtype(pl.Int64, 3) where the second positional arg is a scalar non-dtype.
Common situations: Passing a single dtype name as a string ("numeric") instead of a dtype object, passing a variable that was never validated (often None from an optional config), or passing an index/position by mistake.
Related errors
- invalid dtype: {t!r}
- invalid input for `exclude`\n\nExpected one or more `str` or
- cannot exclude by both column name and dtype
- invalid index value: {idx!r}
- invalid name: {n!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/6497657145aa34e2.
Report an issue: GitHub.