pandas-dev/pandas · error · ValueError
Cannot modify read-only array
Error message
Cannot modify read-only array
What it means
Raised by BaseMaskedArray._pad_or_backfill when copy=False is requested on an array whose backing _data is read-only (self._readonly == True). The in-place fill path (ffill/bfill/pad/backfill with limit_area) cannot mutate read-only buffers, so it refuses before any partial write.
Source
Thrown at pandas/core/arrays/masked.py:259
*,
method: FillnaOptions,
limit: int | None = None,
limit_area: Literal["inside", "outside"] | None = None,
copy: bool = True,
) -> Self:
mask = self._mask
if mask.any():
func = missing.get_fill_func(method, ndim=self.ndim)
npvalues = self._data.T
new_mask = mask.T
if copy:
npvalues = npvalues.copy()
new_mask = new_mask.copy()
else:
if self._readonly:
raise ValueError("Cannot modify read-only array")
if limit_area is not None:
mask = mask.copy()
func(npvalues, limit=limit, mask=new_mask)
if limit_area is not None and not mask.all():
mask = mask.T
neg_mask = ~mask
first = neg_mask.argmax()
last = len(neg_mask) - neg_mask[::-1].argmax() - 1
if limit_area == "inside":
new_mask[:first] |= mask[:first]
new_mask[last + 1 :] |= mask[last + 1 :]
elif limit_area == "outside":
new_mask[first + 1 : last] |= mask[first + 1 : last]
if copy:
return self._simple_new(npvalues.T, new_mask.T)
else:View on GitHub (pinned to 71959b8cb9)
Solutions
- Force a copy first: arr = arr.copy() then arr._pad_or_backfill(method='ffill', copy=False).
- Use the public Series API which defaults copy=True: s.ffill().
- Check arr._readonly and switch to a copy-on-write path when True.
Example fix
# before arr._pad_or_backfill(method='ffill', copy=False) # arr._readonly == True # after arr = arr.copy() arr._pad_or_backfill(method='ffill', copy=False)
Defensive patterns
Strategy: validation
Validate before calling
def writable_or_copy(arr):
if getattr(arr, '_readonly', False):
return arr.copy()
return arr Type guard
def is_writable_masked(arr) -> bool:
return not getattr(arr, '_readonly', False) and arr._data.flags.writeable Prevention
- Default to copy=True for fill operations on potentially shared buffers.
- Detect Arrow-backed or memmap-backed columns and copy before in-place fill.
- Document which sources produce read-only masked arrays in your pipeline.
When it happens
Trigger: Calling arr.ffill(inplace-ish via copy=False), Series.ffill() where the underlying Block is backed by a read-only masked array (e.g. zero-copy from Arrow or shared memory).
Common situations: Arrow-backed nullable columns converted with convert_dtypes(dtype_backend='pyarrow'), memory-mapped or pickled read-only data, copy-on-write pipelines.
Related errors
- Cannot modify read-only array
- No masked accumulation defined for dtype {values.dtype.type}
- No accumulation for {func} implemented on BaseMaskedArray
- Cannot modify read-only array
- Cannot modify read-only array
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/0424dd786fe16cdd.
Report an issue: GitHub.