pandas-dev/pandas · error · ValueError
Cannot modify read-only array
Error message
Cannot modify read-only array
What it means
Raised in `IntervalArray.__setitem__` when `self._readonly` is True. Some IntervalArray instances wrap a read-only memory buffer (e.g. views over a parent array, or buffers marked write-protected); any in-place assignment is refused to avoid silently failing or corrupting shared memory.
Solutions
- Copy before writing: `arr = arr.copy()` then assign.
- Operate at the Series level: `s.iloc[i] = value`, which handles copy semantics.
- Identify the source: if the buffer is unexpectedly read-only, rebuild the array from a writable buffer.
Example fix
# before arr = df['bins'].array # _readonly True arr[0] = pd.Interval(0,1) # after arr = df['bins'].array.copy() arr[0] = pd.Interval(0,1) df['bins'] = arr
Defensive patterns
Strategy: validation
Validate before calling
def ensure_writable(arr):
if getattr(arr, '_readonly', False):
arr = arr.copy()
return arr Type guard
def is_writable_interval_array(arr) -> bool:
return not getattr(arr, '_readonly', False) Try / catch
try:
arr[i] = value
except ValueError as e:
if 'Cannot modify read-only array' in str(e):
arr = arr.copy()
arr[i] = value
else:
raise Prevention
- Call .copy() before mutating arrays obtained as views from Series/DataFrames.
- Prefer in-place edits at the Series level (s.iloc[i] = v).
- Check the _readonly flag when interoping with numpy/cython buffers.
When it happens
Trigger: Calling `arr[i] = value` on an IntervalArray obtained as a view (`.values` of a Series backed by a read-only buffer, or slices flagged as views); writing to an array derived from a numpy read-only array.
Common situations: Operating on `series.array` after the Series was constructed from a read-only numpy buffer; pickle/IPC round-trips that mark buffers read-only; cython/numba interop.
Related errors
- Cannot modify read-only array
- Cannot modify read-only array
- Cannot modify read-only array
- closed keyword does not match dtype.closed
- invalid dtype
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/152e9b641e635931.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/interval.py:696
# scalar
if is_scalar(left) and isna(left):
return self._fill_value
return Interval(left, right, self.closed)
if np.ndim(left) > 1:
# GH#30588 multi-dimensional indexer disallowed
raise ValueError("multi-dimensional indexing not allowed")
# Argument 2 to "_simple_new" of "IntervalArray" has incompatible type
# "Union[Period, Timestamp, Timedelta, NaTType, DatetimeArray, TimedeltaArray,
# ndarray[Any, Any]]"; expected "Union[Union[DatetimeArray, TimedeltaArray],
# ndarray[Any, Any]]"
result = self._simple_new(left, right, dtype=self.dtype) # type: ignore[arg-type]
if getitem_returns_view(self, key):
result._readonly = self._readonly
return result
def __setitem__(self, key, value) -> None:
if self._readonly:
raise ValueError("Cannot modify read-only array")
key = check_array_indexer(self, key)
value_left, value_right = self._validate_setitem_value(value)
self._left[key] = value_left
self._right[key] = value_right
def _cmp_method(self, other, op):
# ensure pandas array for list-like and eliminate non-interval scalars
if is_list_like(other):
if not isinstance(
other, (list, np.ndarray, ExtensionArray)
) and not ops.has_castable_attr(other):
warnings.warn(
f"Operation with {type(other).__name__} is deprecated. "
"In a future version these will be treated as scalar-like. "
"To retain the old behavior, explicitly wrap in a Series "
"instead.",View on GitHub (pinned to 3b7651241d)