pola-rs/polars · error · IndexError

category index out of range: {key}

Error message

category index out of range: {key}

What it means

IndexError raised by a Categorical's CategoriesMapping.__getitem__ when an integer index is outside the category table (negative or >= number of categories). The mapping only stores as many codes as distinct categories, so any out-of-range physical code has no string to return.

Source

Thrown at py-polars/src/polars/datatypes/classes.py:851

        elif phys == "u32":
            return pldt.UInt32
        else:
            msg = "unknown physical dtype"
            raise RuntimeError(msg)

    def is_global(self) -> bool:
        """Returns whether this refers to the global categories."""
        return self._categories.is_global()

    def __getitem__(self, key: str | int) -> str | int:
        if isinstance(key, str):
            if (cat := self._categories.get_cat(key)) is None:
                raise KeyError(key)
            return cat
        elif isinstance(key, int):
            if (s := self._categories.cat_to_str(key)) is None:
                msg = f"category index out of range: {key}"
                raise IndexError(msg)
            return s
        else:
            msg = f"invalid key type {type(key)}; expected str or int"
            raise TypeError(msg)

    def __contains__(self, item: str | int) -> bool:
        if isinstance(item, str):
            return self._categories.get_cat(item) is not None
        elif isinstance(item, int):
            return self._categories.cat_to_str(item) is not None
        else:
            return False

    def __iter__(self) -> Iterator[str | None]:
        for i in range(self._categories.num_cats_upper_bound()):
            yield self._categories.cat_to_str(i)

    def to_series(self) -> Series:

View on GitHub (pinned to 68506541d2)

Solutions

  1. Validate the index: 0 <= i < len(categories) before indexing
  2. Use cat_to_str(key) which returns None for invalid codes
  3. When combining categoricals, cast to String or use Categorical('lexical') / union so codes share one vocabulary

Example fix

# before
label = dtype.categories[1234]
# after
label = dtype.categories.cat_to_str(1234)
if label is None:
    ...  # index out of range
Defensive patterns

Strategy: validation

Validate before calling

if not (0 <= idx < dtype.categories.len()):
    raise IndexError(f'bad category code {idx}')

Type guard

def valid_code(dtype: pl.DataType, idx: int) -> bool:
    return dtype.categories.cat_to_str(idx) is not None

Try / catch

try:
    label = dtype.categories[i]
except IndexError:
    label = None  # stale/foreign physical code

Prevention

When it happens

Trigger: categories[999] on a categorical with fewer categories; using a physical code obtained from a different (larger) categorical vocabulary; negative indices below the mapping's range.

Common situations: Debugging by dumping category codes; joining/concatenating categoricals with mismatched string caches or global category spaces; stale indices saved before a categorical was rebuilt.

Related errors


AI-assisted analysis of pola-rs/polars@68506541d2 (2026-08-28). Data as JSON: /api/errors/fec7d1b40b32266e. Report an issue: GitHub.