pandas-dev/pandas · error · IndexError

only integers, slices (`:`), ellipsis (`...`)…

Error message

only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

What it means

Raised by ArrowExtensionArray.__getitem__ for a scalar indexer that is neither an integer nor something the array/slice/tuple branches handled. The message is intentionally copied from numpy's IndexError. Typical triggers: indexing with a string label, a float like 2.5, or any non-integer scalar.

Solutions

  1. If you meant a label lookup, go through the parent Series/Index: s.loc[label] or s[label].
  2. If you have a float that is mathematically integral, cast: arr[int(idx)].
  3. Validate with is_integer before indexing, or wrap user input with int().
  4. For multi-dimensional style indexing, ensure tuples contain only ints/slices/Ellipsis/None.

Example fix

# before
arr = pd.array([10, 20, 30], dtype="int64[pyarrow]")
arr[1.0]  # raises IndexError

# after
arr[int(1.0)]
Defensive patterns

Strategy: type-guard

Validate before calling

from pandas.api.types import is_integer

def safe_scalar_index(arr, item):
    if is_integer(item):
        return arr[item]
    raise TypeError(f'non-integer scalar indexer: {item!r}')

Type guard

from numbers import Integral
from pandas.api.types import is_scalar

def is_integer_scalar(v) -> bool:
    return is_scalar(v) and isinstance(v, Integral)

Prevention

When it happens

Trigger: arr['foo'] on a positional extension array; arr[2.5]; indexing with a python float that 'looks like' an int; indexing with a None that escaped the Ellipsis/None handling; using a pandas Timedelta/Timestamp scalar as a positional indexer.

Common situations: Confusing label-based access (.loc) with positional access (.iloc/__getitem__); passing dict keys or column names into an extension array; off-by-one errors producing float positions; legacy code assuming object-dtype indexing semantics.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/55f69b74812de448. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/arrow/array.py:933

                return self.take(item)
            elif item.dtype.kind == "b":
                return self._from_pyarrow_array(self._pa_array.filter(item))
            else:
                raise IndexError(
                    "Only integers, slices and integer or "
                    "boolean arrays are valid indices."
                )
        elif isinstance(item, tuple):
            item = unpack_tuple_and_ellipses(item)

        if item is Ellipsis:
            # TODO: should be handled by pyarrow?
            item = slice(None)

        if is_scalar(item) and not is_integer(item):
            # e.g. "foo" or 2.5
            # exception message copied from numpy
            raise IndexError(
                r"only integers, slices (`:`), ellipsis (`...`), numpy.newaxis "
                r"(`None`) and integer or boolean arrays are valid indices"
            )
        # We are not an array indexer, so maybe e.g. a slice or integer
        # indexer. We dispatch to pyarrow.
        value = self._pa_array[item]
        if isinstance(value, pa.ChunkedArray):
            result = self._from_pyarrow_array(value)
            if getitem_returns_view(self, item):
                result._readonly = self._readonly
            return result
        else:
            pa_type = self._pa_array.type
            scalar = value.as_py()
            if scalar is None:
                return self._dtype.na_value
            elif pa.types.is_timestamp(pa_type) and pa_type.unit != "ns":
                # GH 53326

View on GitHub (pinned to 3b7651241d)