pola-rs/polars · error

cannot use Series of dtype {key.dtype!r} for indexing; expec

Error message

cannot use Series of dtype {key.dtype!r} for indexing; expected boolean or integer dtype

What it means

Raised by Series.__setitem__ when the indexing key is a Series whose dtype is neither Boolean (mask) nor integer (positions). The setter supports exactly two key kinds - boolean masks for conditional assignment and integer Series for positional scatter - and rejects anything else, including float index Series and string Series.

Source

Thrown at py-polars/src/polars/series/series.py:1555

            self.scatter(key, value)
            return None
        elif isinstance(value, Sequence) and not isinstance(value, str):
            if self.dtype.is_numeric() or self.dtype.is_temporal():
                self.scatter(key, value)  # type: ignore[arg-type]
                return None
            msg = (
                f"cannot set Series of dtype: {self.dtype!r} with list/tuple as value;"
                " use a scalar value"
            )
            raise TypeError(msg)
        if isinstance(key, Series):
            if key.dtype == Boolean:
                self._s = self.set(key, value)._s
            elif key.dtype.is_integer():
                self._s = self.scatter(key, value)._s
            else:
                msg = f"cannot use Series of dtype {key.dtype!r} for indexing; expected boolean or integer dtype"
                raise TypeError(msg)

        # TODO: implement for these types without casting to series
        elif _check_for_numpy(key) and isinstance(key, np.ndarray):
            if key.dtype == np.bool_:
                # boolean numpy mask
                self._s = self.scatter(np.argwhere(key)[:, 0], value)._s
            else:
                s = self._from_pyseries(
                    PySeries.new_u32("", np.array(key, np.uint32), _strict=True)
                )
                self.__setitem__(s, value)
        elif isinstance(key, (list, tuple)):
            s = self._from_pyseries(sequence_to_pyseries("", key, dtype=UInt32))
            self.__setitem__(s, value)
        else:
            msg = f'cannot use "{key!r}" for indexing'
            raise TypeError(msg)

View on GitHub (pinned to df599052da)

Solutions

  1. Cast the key to the intended kind: `s[key.cast(pl.Int64)] = v` for positions, `s[key.cast(pl.Boolean)] = v` for masks.
  2. Build integer indices explicitly: `pl.Series(range(n), dtype=pl.Int64)` or `np.argwhere(mask).squeeze()`.
  3. Use a Python list of ints, which is converted internally: `s[[0, 1]] = v`.
  4. For condition-based updates prefer `pl.when(...).then(...)` at the frame level.

Example fix

// before
s = pl.Series([1, 2, 3])
idx = pl.Series([0.0, 2.0])
s[idx] = 0  # TypeError

// after
s[idx.cast(pl.Int64)] = 0
# or
s[[0, 2]] = 0
Defensive patterns

Strategy: validation

Validate before calling

def valid_key_series(k: pl.Series) -> bool:
    return k.dtype == pl.Boolean or k.dtype.is_integer()

if isinstance(key, pl.Series):
    assert valid_key_series(key), f'bad key dtype {key.dtype}'

Type guard

def is_valid_index_series(k: pl.Series) -> bool:
    return k.dtype == pl.Boolean or k.dtype.is_integer()

Try / catch

try:
    s[key] = value
except TypeError as e:
    if 'expected boolean or integer dtype' not in str(e):
        raise
    s[key.cast(pl.Int64) if key.dtype.is_float() else key.cast(pl.Boolean)] = value

Prevention

When it happens

Trigger: `s[key_series] = value` where key.dtype is e.g. Float64 (`pl.Series([0.0, 1.0])`), String, or another non-Boolean/non-integer type. Note floats do NOT count as integer: `s[pl.Series([1.5])] = 0` and `s[pl.Series(np.linspace(0, 1, n))] = 0` both raise.

Common situations: Indices produced by numpy float arithmetic (np.linspace, normalized positions, division results) fed directly as keys; passing a string column expecting label-based indexing (pandas `.loc` habit); float masks computed as proportions instead of booleans.

Related errors


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