pandas-dev/pandas · error · TypeError
Invalid value '{item}' for dtype 'str'. Value should be a st
Error message
Invalid value '{item}' for dtype 'str'. Value should be a string or missing value, got '{type(item).__name__}' instead. What it means
Raised by ArrowStringArray.insert() when the item to insert is neither a str instance nor the missing sentinel libmissing.NA. The string[pyarrow] dtype is strictly typed, so inserting an int, float, None (vs NA), or any non-string scalar is rejected at the boundary rather than silently coerced. Callers must explicitly convert or filter non-string values.
Source
Thrown at pandas/core/arrays/string_arrow.py:309
@classmethod
def _from_sequence_of_strings(
cls, strings, *, dtype: ExtensionDtype, copy: bool = False
) -> Self:
return cls._from_sequence(strings, dtype=dtype, copy=copy)
@property
def dtype(self) -> StringDtype: # type: ignore[override]
"""
An instance of 'string[pyarrow]'.
"""
return self._dtype
def insert(self, loc: int, item) -> ArrowStringArray:
if self.dtype.na_value is np.nan and item is np.nan:
item = libmissing.NA
if not isinstance(item, str) and item is not libmissing.NA:
raise TypeError(
f"Invalid value '{item}' for dtype 'str'. Value should be a "
f"string or missing value, got '{type(item).__name__}' instead."
)
return super().insert(loc, item)
def _convert_bool_result(self, values, na=lib.no_default, method_name=None):
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)
View on GitHub (pinned to 71959b8cb9)
Solutions
- Convert the item to str before inserting: `arr.insert(loc, str(item))`.
- Use `pd.NA` (the string dtype's missing value) instead of `None` to represent missingness.
- Filter or coerce upstream so the insert site only ever sees str/pd.NA.
- If you genuinely need mixed types, use dtype=object instead of 'string[pyarrow]'.
Example fix
# before arr.insert(0, 42) # TypeError # after arr.insert(0, str(42)) # or for missing: arr.insert(0, pd.NA)
Defensive patterns
Strategy: type-guard
Validate before calling
import pandas as pd
from pandas._libs import missing as libmissing
def safe_insert(arr, loc, item):
if item is not libmissing.NA and not isinstance(item, str):
item = str(item)
return arr.insert(loc, item) Type guard
from pandas._libs import missing as libmissing
import numpy as np
def is_valid_string_item(item) -> bool:
return isinstance(item, str) or item is libmissing.NA or item is pd.NA Try / catch
try:
arr.insert(loc, item)
except TypeError as e:
if 'Invalid value' in str(e) and 'dtype' in str(e):
arr.insert(loc, str(item))
else:
raise Prevention
- Sanitize all dynamic insert inputs through str() at the source.
- Use pd.NA consistently for missing string values, not None.
- Add a typed helper that wraps insert with validation.
When it happens
Trigger: Calling `arr.insert(loc, 5)`, `arr.insert(loc, None)`, or `arr.insert(loc, 3.14)` on an ArrowStringArray. The guard at string_arrow.py:308 checks `not isinstance(item, str) and item is not libmissing.NA`.
Common situations: Building mixed-type columns dynamically; reading user input that was not sanitized to strings; confusing None (Python null) with pandas NA; passing a numpy.str_ that is actually fine but a numpy int that is not.
Related errors
- Invalid value '{value}' for dtype 'str'. Value should be a s
- Invalid value for dtype 'str'. Value should be a string or m
- Cannot perform reduction '{name}' with string dtype
- bad operand type for unary +: '{self.dtype}'
- Unordered Categoricals can only compare equality or not
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/099ff22eaa53b4fb.
Report an issue: GitHub.