{"record":{"id":"0424dd786fe16cdd","repo":"pandas-dev/pandas","slug":"cannot-modify-read-only-array-0424dd","errorCode":null,"errorMessage":"Cannot modify read-only array","messagePattern":"Cannot modify read-only array","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":259,"sourceCode":"        *,\n        method: FillnaOptions,\n        limit: int | None = None,\n        limit_area: Literal[\"inside\", \"outside\"] | None = None,\n        copy: bool = True,\n    ) -> Self:\n        mask = self._mask\n\n        if mask.any():\n            func = missing.get_fill_func(method, ndim=self.ndim)\n\n            npvalues = self._data.T\n            new_mask = mask.T\n            if copy:\n                npvalues = npvalues.copy()\n                new_mask = new_mask.copy()\n            else:\n                if self._readonly:\n                    raise ValueError(\"Cannot modify read-only array\")\n                if limit_area is not None:\n                    mask = mask.copy()\n            func(npvalues, limit=limit, mask=new_mask)\n\n            if limit_area is not None and not mask.all():\n                mask = mask.T\n                neg_mask = ~mask\n                first = neg_mask.argmax()\n                last = len(neg_mask) - neg_mask[::-1].argmax() - 1\n                if limit_area == \"inside\":\n                    new_mask[:first] |= mask[:first]\n                    new_mask[last + 1 :] |= mask[last + 1 :]\n                elif limit_area == \"outside\":\n                    new_mask[first + 1 : last] |= mask[first + 1 : last]\n\n            if copy:\n                return self._simple_new(npvalues.T, new_mask.T)\n            else:","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/masked.py#L241-L277","documentation":"Raised by BaseMaskedArray._pad_or_backfill when an in-place fill (copy=False) is requested on an array whose _readonly flag is set. pandas marks sliced/shared masked arrays read-only to prevent mutating buffers aliased by other arrays, so it refuses to run the Cython backfill/pad routine that writes into self._data in place.","triggerScenarios":"Calling arr.ffill(), arr.bfill(), or arr._pad_or_backfill(..., copy=False) on a masked ExtensionArray (Int64, Float64, boolean) that was obtained through a slice/view that propagated _readonly=True, or any array explicitly constructed with read-only buffers.","commonSituations":"Filling NA values on a Series backed by a slice of a larger masked array; chaining .ffill() after a view-producing operation; libraries that hand back read-only views to enforce immutability; passing copy=False expecting zero-copy behavior.","solutions":["Pass copy=True (the default) so _pad_or_backfill clones data and mask before writing.","Materialize an independent, writable copy first: arr = arr.copy() then arr.ffill() / arr.bfill().","Avoid requesting in-place fills on views; reassign the result instead of relying on copy=False."],"exampleFix":"// before\narr = parent[start:stop]   # view with _readonly=True\narr._pad_or_backfill(method=\"ffill\", copy=False)  # raises\n// after\narr = parent[start:stop].copy()\nout = arr._pad_or_backfill(method=\"ffill\", copy=True)","handlingStrategy":"validation","validationCode":"if getattr(arr, '_readonly', False):\n    arr = arr.copy()\nout = arr._pad_or_backfill(method='ffill', copy=True)","typeGuard":"def is_writable_masked(arr) -> bool:\n    return not getattr(arr, '_readonly', False)","tryCatchPattern":"try:\n    out = arr._pad_or_backfill(method='ffill', copy=False)\nexcept ValueError as e:\n    if 'read-only' in str(e):\n        out = arr.copy()._pad_or_backfill(method='ffill', copy=False)\n    else:\n        raise","preventionTips":["Default to copy=True for any fill/backfill on potentially shared masked arrays.","Treat masked-array slices as read-only until you explicitly .copy().","Reassign results of fill/ffill/bfill instead of relying on copy=False."],"tags":["pandas","masked-array","read-only","fillna","ffill"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}