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
- If you meant a label lookup, go through the parent Series/Index: s.loc[label] or s[label].
- If you have a float that is mathematically integral, cast: arr[int(idx)].
- Validate with is_integer before indexing, or wrap user input with int().
- 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
- Use Series.loc for label access and reserve raw __getitem__ for integers.
- Cast floats to int explicitly: arr[int(idx)].
- Reject non-integer scalars at the API boundary.
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
- Only integers, slices and integer or boolean arrays are…
- Cannot slice with Ellipsis
- Cannot slice with
- index is out of bounds: must be an integer between
- Indexing with a float is no longer supported. Manually…
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 53326View on GitHub (pinned to 3b7651241d)