pandas-dev/pandas · error · TypeError

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

Error message

Invalid value '{value}' for dtype 'str'. Value should be a string or missing value, got '{type(value).__name__}' instead.

What it means

ArrowStringArray._validate_setitem_value rejects scalar values that are not str and not NA. Setting an int, float, bool, or list scalar into a string[pyarrow] array raises TypeError to keep the strict str dtype.

Solutions

  1. Cast the value to str: s.iloc[0] = str(value).
  2. Use pd.NA for missing values.
  3. If the column will hold numbers, change its dtype with astype instead of assigning into a string column.

Example fix

// before
s.iloc[0] = 100  # TypeError
// after
s.iloc[0] = str(100)
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_setitem_scalar(arr, key, value):
    from pandas.api.types import is_scalar, isna
    if is_scalar(value) and not isinstance(value, str) and not isna(value):
        value = str(value)
    arr[key] = value

Type guard

def is_setitem_valid_string_scalar(value) -> bool:
    from pandas.api.types import is_scalar, isna
    return isinstance(value, str) or (is_scalar(value) and isna(value))

Try / catch

try:
    s.iloc[i] = value
except TypeError as e:
    if "Invalid value" in str(e):
        s.iloc[i] = str(value)
    else:
        raise

Prevention

When it happens

Trigger: s.iloc[0] = 5 on a string[pyarrow] Series; s.iloc[0] = 3.14; s.iloc[0] = True; any scalar non-string setitem after isna() check fails.

Common situations: Assigning cleaned numeric data into a string column without conversion; replacing a NaN cell with a computed numeric value; mis-typed pipeline stages.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/0c7b5c9f5e4d1d63. Report an issue: GitHub.

Appendix: source

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

        validate_na_arg(na, name="na")
        if self.dtype.na_value is np.nan:
            if na is lib.no_default or isna(na):
                # NaN propagates as False
                values = values.fill_null(False)
            else:
                values = values.fill_null(na)
            return values.to_numpy()
        elif na is not lib.no_default and not isna(na):  # pyright: ignore [reportGeneralTypeIssues]
            values = values.fill_null(na)
        return BooleanDtype().__from_arrow__(values)

    def _validate_setitem_value(self, value):
        """Maybe convert value to be pyarrow compatible."""
        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)

View on GitHub (pinned to 3b7651241d)