pandas-dev/pandas · error · TypeError

Invalid value for dtype 'str'. Value should be a string or m

Error message

Invalid value for dtype 'str'. Value should be a string or missing value (or array of those).

What it means

Raised by ArrowStringArray._validate_setitem_value() for the array-like branch: when the assigned sequence is not 1-dimensional or is not composed entirely of strings/missing values. The check at string_arrow.py:345 uses lib.is_string_array(value, skipna=True) and ndim==1, so a list/tuple/ndarray containing any non-string non-NA element (e.g. an int or float) is rejected.

Source

Thrown at pandas/core/arrays/string_arrow.py:348

        if is_scalar(value):
            if isna(value):
                value = None
            elif not isinstance(value, str):
                raise TypeError(
                    f"Invalid value '{value}' for dtype 'str'. Value should be a "
                    f"string or missing value, got '{type(value).__name__}' instead."
                )
        elif isinstance(value, type(self)):
            pass
        else:
            if not is_array_like_deprecate_non_pandas(value):
                value = np.asarray(value, dtype=object)
            else:
                value = np.asarray(value)
            if len(value) and not (
                value.ndim == 1 and 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 super()._validate_setitem_value(value)

    def isin(self, values: ArrayLike) -> npt.NDArray[np.bool_]:
        value_set = [
            pa_scalar.as_py()
            for pa_scalar in [pa.scalar(value, from_pandas=True) for value in values]
            if pa_scalar.type in (pa.string(), pa.null(), pa.large_string())
        ]

        # short-circuit to return all False array.
        if not value_set:
            return np.zeros(len(self), dtype=bool)

        result = pc.is_in(
            self._pa_array, value_set=pa.array(value_set, type=self._pa_array.type)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Convert the sequence element-wise to str first: `s[:] = [str(x) for x in values]` or `pd.array(values, dtype='string[pyarrow]')`.
  2. If the source is a Series, cast it: `s[:] = other.astype('string[pyarrow]')`.
  3. Replace any non-string sentinels with pd.NA before assignment.
  4. Ensure the value is 1-D; reshape or flatten 2-D inputs explicitly.

Example fix

# before
s = pd.Series(['a','b','c'], dtype='string[pyarrow]')
s[:] = [1, 2, 3]  # TypeError
# after
s[:] = [str(x) for x in [1, 2, 3]]
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
from pandas._libs import lib

def safe_setitem_array(arr, loc, values):
    values = np.asarray(values, dtype=object)
    if values.ndim != 1 or not lib.is_string_array(values, skipna=True):
        values = np.array([str(x) for x in values], dtype=object)
    arr[loc] = values

Type guard

import numpy as np
from pandas._libs import lib
def is_1d_string_array(values) -> bool:
    arr = np.asarray(values, dtype=object)
    return arr.ndim == 1 and lib.is_string_array(arr, skipna=True)

Try / catch

try:
    s[:] = values
except TypeError as e:
    if 'Invalid value for dtype' in str(e):
        s[:] = [str(x) for x in values]
    else:
        raise

Prevention

When it happens

Trigger: Assigning `s[:] = [1, 2, 3]`, `s[:] = np.array([1.0, 2.0])`, or a 2-D array to a 'string[pyarrow]' Series. Triggered when the value passes is_scalar (False) and is not an ArrowStringArray, landing in the array validation branch.

Common situations: Bulk-assigning a numeric column's values into a string column; replacing a slice with output of a numeric reduction; feeding unparsed JSON/CSV cells directly.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/4554fdfe59597734. Report an issue: GitHub.