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

  1. Cast the Series to an integer dtype before indexing: `s[pl.Series([0.0, 1.0]).cast(pl.UInt32)]`.
  2. If the values are labels not positions, use a filter/join or `df.with_row_index()` to convert labels to positions first.
  3. 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

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


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 s

View on GitHub (pinned to fe841f959e)