pandas-dev/pandas · error · ValueError

setting an array element with a sequence.

Error message

setting an array element with a sequence.

What it means

StringArray.__setitem__ rejects the case where a scalar index key targets a single slot but the supplied value is a non-scalar sequence (e.g. a list or array). pandas enforces single-position assignment stays single-valued to avoid silently nesting sequences inside object-backed string storage, which would corrupt the array's invariant that each element is a Python str or NA.

Solutions

  1. Assign a scalar string or NA when indexing a single position: s.iloc[0] = 'a'.
  2. If you intend to set multiple cells, use a matching-length boolean or slice key: s.iloc[[0,1]] = ['a','b'].
  3. If the value is a one-element array, extract the scalar first: s.iloc[i] = arr[0].
  4. If you must store sequences per row, keep the column dtype as object instead of 'string'.

Example fix

// before
s = pd.Series(['x','y'], dtype='string')
s.iloc[0] = ['a','b']  # ValueError
// after
s.iloc[[0,1]] = ['a','b']  # set multiple cells
# or for a single cell
s.iloc[0] = 'a'
Defensive patterns

Strategy: validation

Validate before calling

from pandas.core.dtypes.common import is_scalar
def assign_single_string_cell(arr, i, value):
    if not is_scalar(value):
        raise ValueError(f"Refusing to assign non-scalar to single cell {i}; use a slice/boolean key for arrays.")
    arr[i] = value

Type guard

def is_assignable_to_single_cell(value) -> bool:
    from pandas.api.types import is_scalar
    return is_scalar(value)

Try / catch

try:
    s.iloc[i] = value
except ValueError as e:
    if 'setting an array element with a sequence' in str(e):
        s.iloc[[i, *extra]] = value  # or use scalar
    else:
        raise

Prevention

When it happens

Trigger: Assigning a list/tuple/np.ndarray to a single integer position of a StringArray or string-dtyped Series: `s.iloc[0] = ['a','b']` or `arr[3] = np.array(['x'])`. Triggered inside __setitem__ when lib.is_scalar(key) is True but lib.is_scalar(value) is False after _validate_setitem_value.

Common situations: Loop-driven assignment that builds a list per iteration and writes it into one cell; a broadcast mistake where df.loc[i, 'col'] = some_list; switching dtype from object to 'string' and hitting the newly-enforced scalar invariant.

Related errors


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

Appendix: source

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

                value = np.asarray(value)
            if len(value) and not 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 value

    def __setitem__(self, key, value) -> None:
        if self._readonly:
            raise ValueError("Cannot modify read-only array")

        value = self._validate_setitem_value(value)

        key = check_array_indexer(self, key)
        scalar_key = lib.is_scalar(key)
        scalar_value = lib.is_scalar(value)
        if scalar_key and not scalar_value:
            raise ValueError("setting an array element with a sequence.")

        if not scalar_value:
            if value.dtype == self.dtype:
                value = value._ndarray
            else:
                value = np.asarray(value)
                mask = isna(value)
                if mask.any():
                    value = value.copy()
                    value[isna(value)] = self.dtype.na_value

        super().__setitem__(key, value)

    def _putmask(self, mask: npt.NDArray[np.bool_], value) -> None:
        # the super() method NDArrayBackedExtensionArray._putmask uses
        # np.putmask which doesn't properly handle None/pd.NA, so using the
        # base class implementation that uses __setitem__
        ExtensionArray._putmask(self, mask, value)

View on GitHub (pinned to 3b7651241d)