pandas-dev/pandas · error · IndexError
index is out of bounds for axis 0 with size
Error message
index {key} is out of bounds for axis 0 with size {n} What it means
In __setitem__'s integer-key fast path, after normalizing negative indices (key += n) the code checks 0 <= key < n. If the resolved index falls outside the array length, it raises IndexError with the standard numpy-style message naming axis 0 and the size. This matches ndarray.__setitem__ semantics.
Solutions
- Validate 0 <= key < len(arr) (or -len(arr) <= key < 0) before assignment.
- Resize the structure (append/reindex) instead of writing past the end.
- Re-derive the index after any operation that changes array length.
Example fix
// before
s = pd.Series([1, 2, 3], dtype="int64[pyarrow]")
s.iloc[5] = 99
// after
s = pd.Series([1, 2, 3], dtype="int64[pyarrow]")
if 0 <= 5 < len(s):
s.iloc[5] = 99 Defensive patterns
Strategy: validation
Validate before calling
def safe_pos_setitem(arr, key, value):
n = len(arr)
if key < 0:
key += n
if not 0 <= key < n:
raise IndexError(f"index {key} out of range [0,{n})")
arr[key] = value Type guard
def index_in_range(arr, key) -> bool:
n = len(arr)
k = key + n if key < 0 else key
return 0 <= k < n Try / catch
try:
s.iloc[i] = v
except IndexError:
# resize or reindex, then retry
... Prevention
- Bounds-check integer keys before iloc assignment.
- Re-derive indices after filtering.
When it happens
Trigger: Assigning to a single position with an out-of-range integer index on a pyarrow-backed Series/array, e.g. s.iloc[10] = x where len(s) <= 10.
Common situations: Loop indices computed without bounds check; off-by-one after filtering; assigning into an array sized against stale metadata.
Related errors
- out of bounds value in 'indices'.
- cannot do a non-empty take
- Length of indexer and values mismatch
- ambiguous is not supported.
- is not supported
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/5b4a9cfd006f6ae8.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/arrow/array.py:2917
if com.is_null_slice(key):
# fast path (GH50248)
if (
isinstance(value, (pa.Array, pa.ChunkedArray))
and value.type == self._pa_array.type
and len(value) == len(self)
):
data = value
else:
data = self._if_else(True, value, self._pa_array)
elif is_integer(key):
# fast path
key = cast("int", key)
n = len(self)
if key < 0:
key += n
if not 0 <= key < n:
raise IndexError(
f"index {key} is out of bounds for axis 0 with size {n}"
)
if isinstance(value, pa.Scalar):
value = value.as_py()
elif is_list_like(value):
raise ValueError("Length of indexer and values mismatch")
chunks = [
*self._pa_array[:key].chunks,
pa.array([value], type=self._pa_array.type, from_pandas=is_nan_na()),
*self._pa_array[key + 1 :].chunks,
]
data = pa.chunked_array(chunks).combine_chunks()
elif is_bool_dtype(key):
key = np.asarray(key, dtype=np.bool_)
data = self._replace_with_mask(self._pa_array, key, value)
elif is_scalar(value) or isinstance(value, pa.Scalar):View on GitHub (pinned to 3b7651241d)