pandas-dev/pandas · error · ValueError
Invalid value in 'indices'. Must be between -1 and the lengt
Error message
Invalid value in 'indices'. Must be between -1 and the length of the array.
What it means
ValueError from SparseArray._take_with_fill when allow_fill=True and the minimum index is less than -1. With allow_fill, -1 is the only legal sentinel (it means 'use fill_value'); anything smaller is invalid.
Source
Thrown at pandas/core/arrays/sparse/array.py:1175
dtype = None
if indices.size == 0:
result = np.array([], dtype="object")
dtype = self.dtype
elif allow_fill:
result = self._take_with_fill(indices, fill_value=fill_value)
else:
return self._take_without_fill(indices)
return type(self)(
result, fill_value=self.fill_value, kind=self.kind, dtype=dtype
)
def _take_with_fill(self, indices, fill_value=None) -> np.ndarray:
if fill_value is None:
fill_value = self.dtype.na_value
if indices.min() < -1:
raise ValueError(
"Invalid value in 'indices'. Must be between -1 "
"and the length of the array."
)
if indices.max() >= len(self):
raise IndexError("out of bounds value in 'indices'.")
if len(self) == 0:
# Empty... Allow taking only if all empty
if (indices == -1).all():
dtype = np.result_type(self.sp_values, type(fill_value))
taken = np.empty_like(indices, dtype=dtype)
taken.fill(fill_value)
return taken
else:
raise IndexError("cannot do a non-empty take from an empty axes.")
# sp_indexer may be -1 for two reasonsView on GitHub (pinned to 3b7651241d)
Solutions
- Clamp negatives: indices = np.where(indices < -1, -1, indices) if you want fill, or drop allow_fill for true negative indexing.
- Use allow_fill=False (default) to use standard negative positions.
- Validate indices.min() >= -1 before calling take with allow_fill=True.
Example fix
// before arr.take([-2, 0], allow_fill=True) # raises // after arr.take([0, 0], allow_fill=True) # or use allow_fill=False with [-2, 0]
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def clamped_fill_indices(indices):
arr_idx = np.asarray(indices)
arr_idx[arr_idx < -1] = -1
return arr_idx Type guard
def fill_indices_valid(indices) -> bool:
import numpy as np
return bool(np.asarray(indices).min() >= -1) Try / catch
try:
arr.take(indices, allow_fill=True)
except ValueError as e:
if 'Must be between -1' in str(e):
out = arr.take(clamped_fill_indices(indices), allow_fill=True)
else:
raise Prevention
- Remember -1 is the only legal sentinel with allow_fill=True.
- Drop allow_fill for standard negative indexing.
- Validate min(indices) >= -1 before fill-mode take.
When it happens
Trigger: arr.take([-2, 0, 3], allow_fill=True); computing indices with an off-by-one negative shift and forwarding them.
Common situations: Mixing allow_fill=True semantics (which use -1 as sentinel) with normal negative indexing (which uses -n..-1).
Related errors
- 'indices' must be an array, not a scalar '{indices}'.
- out of bounds value in 'indices'.
- cannot do a non-empty take from an empty axes.
- Cannot slice with '{key}'
- {k} is not a valid identifier
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/b5a961ba3e3251bf.
Report an issue: GitHub.