pola-rs/polars · error · TypeError
cannot treat Series of type {s.dtype} as indices
Error message
cannot treat Series of type {s.dtype} as indices What it means
_convert_series_to_indices (getitem.py:363) accepts only integer Series as positional row indices; a Boolean Series deliberately routes to the boolean-mask error, and any other dtype (float, String, temporal, categorical) cannot be interpreted as positions and raises this TypeError naming s.dtype.
Source
Thrown at py-polars/src/polars/_utils/getitem.py:363
# - pl.UInt32 (polars) or pl.UInt64 (polars_u64_idx) Series indexes.
# - Other unsigned Series indexes are converted to pl.UInt32 (polars)
# or pl.UInt64 (polars_u64_idx).
# - Signed Series indexes are converted pl.UInt32 (polars) or
# pl.UInt64 (polars_u64_idx) after negative indexes are converted
# to absolute indexes.
# pl.UInt32 (polars) or pl.UInt64 (polars_u64_idx).
idx_type = get_index_type()
if s.dtype == idx_type:
return s
if not s.dtype.is_integer():
if s.dtype == Boolean:
_raise_on_boolean_mask()
else:
msg = f"cannot treat Series of type {s.dtype} as indices"
raise TypeError(msg)
if s.len() == 0:
return pl.Series(s.name, [], dtype=idx_type)
if idx_type == UInt32:
if s.dtype in {Int64, UInt64} and s.max() >= U32_MAX: # type: ignore[operator]
msg = "index positions should be smaller than 2^32"
raise ValueError(msg)
if s.dtype == Int64 and s.min() < -U32_MAX: # type: ignore[operator]
msg = "index positions should be greater than or equal to -2^32"
raise ValueError(msg)
if s.dtype.is_signed_integer():
if s.min() < 0: # type: ignore[operator]
if idx_type == UInt32:
idxs = s.cast(Int32) if s.dtype in {Int8, Int16} else s
else:
idxs = s.cast(Int64) if s.dtype in {Int8, Int16, Int32} else sView on GitHub (pinned to df599052da)
Solutions
- Cast to integer positions: df[idx.cast(pl.Int64)] (round first if fractional: idx.round(0).cast(pl.Int64))
- For value-based row selection use df.filter(pl.col('id').is_in(values)) or a join
- For name-based selection of columns, put the string Series in the column slot or use df.select(names)
Example fix
# before df[pl.Series([1.0, 2.0])] # float Series cannot be indices # after df[pl.Series([1.0, 2.0]).cast(pl.Int64)]
Defensive patterns
Strategy: type-guard
Validate before calling
if not idx.dtype.is_integer():
if idx.dtype == pl.Boolean:
raise TypeError("use df.filter(mask) for boolean row masks")
idx = idx.cast(pl.Int64)
df[idx] Type guard
import polars as pl
def is_index_series(s: pl.Series) -> bool:
return s.dtype.is_integer() Prevention
- Cast computed float indices to Int64 before passing as row selectors
- Use is_in/filter for value-based lookups instead of string Series
- Remember polars indexing is positional, not label-based
When it happens
Trigger: df[pl.Series(['a', 'b'])] (attempting label-based row selection); df[pl.Series([0.5, 1.0])] (float indices); s[pl.Series(['x'])] on a Series; passing an uncapped result of np.argmax-like computations held in a float Series.
Common situations: Expecting pandas .loc label semantics; using a float column of computed indices without casting; passing a string column of keys instead of using is_in.
Related errors
- cannot select rows using key of type {qualified_type_name(ke
- only 1D NumPy arrays can be treated as indices
- cannot treat NumPy array of type {arr.dtype} as indices
- cannot select columns using key of type {qualified_type_name
- index positions should be smaller than 2^32
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/259c66ee6192039f.
Report an issue: GitHub.