pola-rs/polars · error
cannot treat Series of type
Error message
cannot treat Series of type {s.dtype} as indices What it means
Raised by `_convert_series_to_indices` when a Series used as a row-index in `__getitem__`/`_select_rows` has a dtype that is neither an integer nor a boolean (e.g. Float64, Utf8/str, Categorical). Polars only accepts integer-position Series as row selectors; anything else is ambiguous, so it fails fast with a TypeError.
Solutions
- Cast the Series to an integer dtype before indexing: `s[pl.Series([0.0, 1.0]).cast(pl.UInt32)]`.
- If the values are labels not positions, use a filter/join or `df.with_row_index()` to convert labels to positions first.
- If a boolean selector was intended, pass the boolean Series to `.filter()` instead of `__getitem__`.
Example fix
// before idx = (pl.int_range(0, 10) / 2).unique() sub = s[idx] # TypeError: cannot treat Series of type f64 as indices // after idx = (pl.int_range(0, 10) // 2).unique() sub = s[idx]
Defensive patterns
Strategy: validation
Validate before calling
if isinstance(idx, pl.Series) and not idx.dtype.is_integer():
if idx.dtype == pl.Boolean:
raise ValueError("use .filter(mask) instead of boolean masking via __getitem__")
idx = idx.cast(pl.UInt32) Type guard
def is_int_series(x) -> bool:
return isinstance(x, pl.Series) and x.dtype.is_integer() Try / catch
try:
sub = s[idx_series]
except TypeError as e:
if "as indices" in str(e):
sub = s.filter(idx_series) if idx_series.dtype == pl.Boolean else s[idx_series.cast(pl.UInt32)]
else:
raise Prevention
- Always build index Series with integer ops (// not /).
- Validate `idx.dtype.is_integer()` before `__getitem__`.
- Route boolean masks to `.filter()` by habit.
When it happens
Trigger: Calling `s[some_series]` or `df[series]` where `some_series` contains floats or strings instead of integer positions, e.g. `s[pl.Series([0.0, 1.0])]` or indexing a DataFrame with a Series of column names where rows are expected.
Common situations: Building index Series from arithmetic that promotes ints to floats (`pl.int_range(...) / 2`), receiving index data from JSON/CSV parsed as floats or strings, or accidentally swapping row-index and column-name selectors.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- cannot treat NumPy array of type
- cannot use Series of dtype
- expected type 'int | str', got
- only 1D NumPy arrays can be treated as indices
- activate dtype
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/259c66ee6192039f.
Report an issue: GitHub.
Appendix: 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 fe841f959e)