pandas-dev/pandas · error · ValueError
Cannot modify read-only array
Error message
Cannot modify read-only array
What it means
StringArray.__setitem__ checks the _readonly flag at the top and raises ValueError if the array is read-only. Read-only state is set when the underlying ndarray has writeable=False (e.g., from np.frombuffer, memory mapping, or explicit flags.writeable=False) or when the array is a view into protected memory.
Source
Thrown at pandas/core/arrays/string_.py:871
value = extract_array(value, extract_numpy=True)
if not is_array_like_deprecate_non_pandas(value):
value = np.asarray(value, dtype=object)
elif isinstance(value.dtype, type(self.dtype)):
return value
else:
# cast categories and friends to arrays to see if values are
# compatible, compatibility with arrow backed strings
value = np.asarray(value)
if len(value) and not lib.is_string_array(value, skipna=True):
raise TypeError(
"Invalid value for dtype 'str'. Value should be a "
"string or missing value (or array of those)."
)
return value
def __setitem__(self, key, value) -> None:
if self._readonly:
raise ValueError("Cannot modify read-only array")
value = self._validate_setitem_value(value)
key = check_array_indexer(self, key)
scalar_key = lib.is_scalar(key)
scalar_value = lib.is_scalar(value)
if scalar_key and not scalar_value:
raise ValueError("setting an array element with a sequence.")
if not scalar_value:
if value.dtype == self.dtype:
value = value._ndarray
else:
value = np.asarray(value)
mask = isna(value)
if mask.any():
value = value.copy()
value[isna(value)] = self.dtype.na_valueView on GitHub (pinned to 71959b8cb9)
Solutions
- Copy the array before mutating: arr = arr.copy().
- Avoid setting arr.flags.writeable = False on arrays you intend to modify.
- Detect read-only state up front and branch to a copy path.
Example fix
// before readonly_arr[0] = 'x' // after arr = readonly_arr.copy() arr[0] = 'x'
Defensive patterns
Strategy: validation
Validate before calling
if getattr(string_array, '_readonly', False):
string_array = string_array.copy()
string_array[i] = 'x' Type guard
def is_writable(arr) -> bool:
return not getattr(arr, '_readonly', False) Prevention
- Copy arrays before mutating when they may originate from read-only memory.
- Do not set arr.flags.writeable = False on arrays you later modify.
- Check the _readonly flag at the start of mutation paths.
When it happens
Trigger: Calling string_array[i] = 'x' on an array whose _readonly is True, e.g., one created from a memory-mapped buffer, a zero-copy slice of a read-only buffer, or after arr.flags.writeable = False on the backing ndarray.
Common situations: Loading data via mmap or shared memory; operating on arrays returned by libraries that mark buffers read-only; defensive copies omitted in a pipeline.
Related errors
- Cannot change data-type for string array.
- Invalid value for dtype 'str'. Value should be a string or m
- setting an array element with a sequence.
- {left_base!r} is not {right_base!r}
- {left_base!r} is {right_base!r}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/5d02ab71742ccb47.
Report an issue: GitHub.