pandas-dev/pandas · error · ValueError

StringArray requires a sequence of strings or NaN. Got '{sel

Error message

StringArray requires a sequence of strings or NaN. Got '{self._ndarray.dtype}' dtype instead.

What it means

NaN-semantics counterpart of error 428: after the content check, _validate requires the ndarray dtype to be object for the np.nan-na_value variant. A typed ndarray (int64, float64, '<U') is rejected. Note: the source string at line 744 is missing the f-string prefix, so the literal text '{self._ndarray.dtype}' appears un-interpolated in the message.

Source

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

            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

    @classmethod
    def _from_sequence(

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Cast the ndarray to object dtype first: np.array(values, dtype=object).
  2. Use pd.array(values, dtype='str') which handles the dtype internally.
  3. Convert '<U' arrays via .astype(object).

Example fix

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

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

Strategy: validation

Validate before calling

import numpy as np
values = np.asarray(values)
if values.dtype != object:
    values = values.astype(object)
arr = pd.array(values, dtype='str')

Type guard

import numpy as np

def is_object_ndarray(values) -> bool:
    return isinstance(values, np.ndarray) and values.dtype == object

Prevention

When it happens

Trigger: Constructing StringArray(np.array([1, 2, 3]), dtype=StringDtype(na_value=np.nan)), or passing a '<U' or numeric ndarray under NaN semantics.

Common situations: Using the experimental 'str' dtype with raw numpy arrays not cast to object.

Related errors


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