pola-rs/polars · error

cannot use "{key!r}" for indexing

Error message

cannot use "{key!r}" for indexing

What it means

The fallback raise in Series.__setitem__: the key is not an int, not a Series, not a numpy ndarray, and not a list/tuple, so Polars cannot interpret it as an index and prints the offending key via repr(). Notably, slices are NOT handled by this setter, so `s[0:2] = v` lands here too.

Source

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

                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)

    def __array__(
        self,
        dtype: np.dtype[Any] | None = None,
        copy: bool | None = None,  # noqa: FBT001
    ) -> np.ndarray[Any, Any]:
        """
        Return a NumPy ndarray with the given data type.

        This method ensures a Polars Series can be treated as a NumPy ndarray.
        It enables `np.asarray` and NumPy universal functions.

        See the NumPy documentation for more information:
        https://numpy.org/doc/stable/user/basics.interoperability.html#the-array-method

        See Also
        --------
        __array_ufunc__

View on GitHub (pinned to df599052da)

Solutions

  1. Replace slice keys with explicit positions: `s[[0, 1]] = v`, `s[np.arange(0, 2)] = v`, or `s[list(range(0, 2))] = v`.
  2. Replace slice keys with a boolean mask: `s[[True, True] + [False] * (s.len() - 2)] = v`.
  3. For label-based logic, remember Polars Series are positional - do assignment in a DataFrame with expressions instead.
  4. Coerce float indices to int: `s[int(i)] = v`.

Example fix

// before
s = pl.Series([1, 2, 3])
s[0:2] = 0  # TypeError: cannot use "slice(0, 2, None)" for indexing

// after
s[[0, 1]] = 0
# or a mask:
s[np.arange(s.len()) < 2] = 0
Defensive patterns

Strategy: validation

Validate before calling

def normalize_key(s: pl.Series, key):
    if isinstance(key, slice):
        key = list(range(*key.indices(s.len())))
    if isinstance(key, float):
        key = int(key)
    assert isinstance(key, (int, list, tuple, pl.Series)) or _is_np(key), f'bad key {key!r}'
    return key

Type guard

def is_supported_setitem_key(key) -> bool:
    return isinstance(key, (int, list, tuple)) or type(key).__module__.startswith('numpy') or isinstance(key, pl.Series)

Try / catch

try:
    s[key] = value
except TypeError as e:
    if 'for indexing' not in str(e):
        raise
    s[list(range(key.start or 0, key.stop or s.len(), key.step or 1))] = value

Prevention

When it happens

Trigger: `s[0:2] = 5` (slice key), `s['colname'] = 1` (string key), `s[{'a': 1}] = 1` (dict key), `s[1.5] = 0` (float key - only plain int is special-cased at the top).

Common situations: Pandas slice-assignment habits (`s.iloc[0:2] = 5`); trying label-based ('set by column name') assignment; float indices from computed positions; autocompleted generic code passing through the wrong key type.

Related errors


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