pandas-dev/pandas · error · ValueError

StringArray requires a sequence of strings or NaN

Error message

StringArray requires a sequence of strings or NaN

What it means

The NaN-semantics branch of StringArray._validate (used when dtype.na_value is np.nan, i.e. the 'str' dtype). It calls lib.is_string_array(ndarray, skipna=True) and raises ValueError if any non-NaN element is not a str. Identical logic to the NA branch but for the NumPy-semantics string dtype.

Source

Thrown at pandas/core/arrays/string_.py:742

                    "StringArray requires a sequence of strings or pandas.NA"
                )
            if self._ndarray.dtype != "object":
                raise ValueError(
                    "StringArray requires a sequence of strings or pandas.NA. Got "
                    f"'{self._ndarray.dtype}' dtype instead."
                )
            # Check to see if need to convert Na values to pd.NA
            if self._ndarray.ndim > 2:
                # Ravel if ndims > 2 b/c no cythonized version available
                lib.convert_nans_to_NA(self._ndarray.ravel("K"))
            else:
                lib.convert_nans_to_NA(self._ndarray)
        else:
            # Validate that we only store NaN or strings.
            if len(self._ndarray) and not lib.is_string_array(
                self._ndarray, skipna=True
            ):
                raise ValueError("StringArray requires a sequence of strings or NaN")
            if self._ndarray.dtype != "object":
                raise ValueError(
                    "StringArray requires a sequence of strings "
                    "or NaN. Got '{self._ndarray.dtype}' dtype instead."
                )
            # TODO validate or force NA/None to NaN

    def _validate_scalar(self, value):
        # used by NDArrayBackedExtensionIndex.insert
        if isna(value):
            return self.dtype.na_value
        elif not isinstance(value, str):
            raise TypeError(
                f"Invalid value '{value}' for dtype '{self.dtype}'. Value should be a "
                f"string or missing value, got '{type(value).__name__}' instead."
            )
        return value

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Pre-convert all non-missing values to str.
  2. Use pd.array(values, dtype='str') or _from_sequence which coerces.
  3. Ensure only str and np.nan/None appear in the object array.

Example fix

// before
arr = pd.arrays.StringArray(np.array([1, 'a'], dtype=object), dtype=pd.StringDtype(na_value=np.nan))

// after
arr = pd.array([1, 'a'], dtype='str')
Defensive patterns

Strategy: validation

Validate before calling

clean = [str(v) if not (v is None or v is pd.NA) else v for v in values]
arr = pd.array(clean, dtype='str')

Type guard

import pandas as pd
import numpy as np

def all_strings_or_nan(values) -> bool:
    return all(isinstance(v, str) or v is None or (isinstance(v, float) and np.isnan(v)) for v in values)

Prevention

When it happens

Trigger: Constructing StringArray(np.array([1, 'a'], dtype=object), dtype=StringDtype(na_value=np.nan)), or using the experimental 'str' dtype with mixed non-string content.

Common situations: Opting into NumPy string semantics (using_string_dtype) and feeding uncoerced mixed-type object arrays.

Related errors


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