pandas-dev/pandas · error · ValueError

key must be an int or slice, got {type(key).__name__}

Error message

key must be an int or slice, got {type(key).__name__}

What it means

ListAccessor.__getitem__ only accepts an int (single element index) or a slice. Any other key type (str, list, float, np.ndarray) raises ValueError naming the offending type. This prevents confusing list-element indexing with struct field access or fancy indexing, neither of which the accessor supports.

Source

Thrown at pandas/core/arrays/arrow/accessors.py:195

            # TODO: Support negative start/stop/step, ideally this would be added
            # upstream in pyarrow.
            start, stop, step = key.start, key.stop, key.step
            if start is None:
                # TODO: When adding negative step support
                #  this should be set to last element of array
                # when step is negative.
                start = 0
            if step is None:
                step = 1
            sliced = pc.list_slice(self._pa_array, start, stop, step)
            return Series(
                sliced,
                dtype=ArrowDtype(sliced.type),
                index=self._data.index,
                name=self._data.name,
            )
        else:
            raise ValueError(f"key must be an int or slice, got {type(key).__name__}")

    def __iter__(self) -> Iterator:
        raise TypeError(f"'{type(self).__name__}' object is not iterable")

    def flatten(self) -> Series:
        """
        Flatten list values.

        Each list element is expanded into separate rows, preserving the
        original index. The resulting Series may have a longer length than
        the original if lists contain more than one element.

        Returns
        -------
        pandas.Series
            The data from all lists in the series flattened.

        See Also

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use an int (s.list[0]) or a slice (s.list[0:2]) for indexing.
  2. For multiple element positions, call pc.list_element per index, or flatten first with s.list.flatten().

Example fix

// before
s.list[[0, 1]]
// after
import pyarrow.compute as pc
pd.Series(pc.list_element(s.array._pa_array, 0), index=s.index)
Defensive patterns

Strategy: type-guard

Validate before calling

def list_get(s, key):
    if not isinstance(key, (int, slice)):
        raise TypeError(f"key must be int or slice, got {type(key).__name__}")
    return s.list[key]

Type guard

def is_int_or_slice(k) -> bool:
    return isinstance(k, (int, slice))

Prevention

When it happens

Trigger: s.list['a'], s.list[[0,1]], s.list[1.0], or s.list[np.array([0,1])] on a list[pyarrow] Series.

Common situations: Confusing .list indexing with .struct.field for named access; expecting fancy/boolean indexing on list elements.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/393610b54f743394. Report an issue: GitHub.