pandas-dev/pandas · error · ValueError
Storage must be 'python' or 'pyarrow'. Got {storage} instead
Error message
Storage must be 'python' or 'pyarrow'. Got {storage} instead. What it means
StringDtype.__init__ validates that the storage argument is exactly one of 'python' or 'pyarrow'. Any other value (including None after config resolution, or typos) raises ValueError. When storage is None it is first resolved from pd.options.mode.string_storage, so a misconfigured global option can also surface here.
Source
Thrown at pandas/core/arrays/string_.py:212
_metadata = ("storage", "_na_value") # type: ignore[assignment]
def __init__(
self,
storage: str | None = None,
na_value: libmissing.NAType | float = libmissing.NA,
) -> None:
# infer defaults
if storage is None:
storage = config["mode"]["string_storage"]
if storage == "auto":
if HAS_PYARROW:
storage = "pyarrow"
else:
storage = "python"
# validate options
if storage not in {"python", "pyarrow"}:
raise ValueError(
f"Storage must be 'python' or 'pyarrow'. Got {storage} instead."
)
if storage == "pyarrow" and not HAS_PYARROW:
raise ImportError(
f"pyarrow>={PYARROW_MIN_VERSION} is required for PyArrow "
"backed StringArray."
)
if isinstance(na_value, float) and np.isnan(na_value):
# when passed a NaN value, always set to np.nan to ensure we use
# a consistent NaN value (and we can use `dtype.na_value is np.nan`)
na_value = np.nan
elif na_value is not libmissing.NA:
raise ValueError(f"'na_value' must be np.nan or pd.NA, got {na_value}")
self._storage = cast("str", storage)
self._na_value = na_value
View on GitHub (pinned to 71959b8cb9)
Solutions
- Use exactly 'python' or 'pyarrow' as the storage value.
- If using config, verify pd.options.mode.string_storage is 'python' or 'pyarrow' before relying on storage=None.
- Validate dynamic storage strings against {'python','pyarrow'} before passing to StringDtype.
Example fix
// before dtype = pd.StringDtype(storage='numpy') // after dtype = pd.StringDtype(storage='python')
Defensive patterns
Strategy: validation
Validate before calling
VALID_STORAGES = {'python', 'pyarrow'}
storage = 'python' if storage not in VALID_STORAGES else storage
dtype = pd.StringDtype(storage=storage) Prevention
- Restrict storage to the literals 'python' or 'pyarrow'.
- Validate pd.options.mode.string_storage if you pass storage=None.
- Centralize dtype construction in a helper that checks the storage value.
When it happens
Trigger: Calling StringDtype(storage='numpy'), StringDtype(storage='foo'), pd.array(data, dtype='string[foo]'), or setting pd.options.mode.string_storage to an invalid value and then constructing a StringDtype with storage=None.
Common situations: Typos in dtype strings like 'string[numpy]' or 'string[arrow]'; programmatically building storage names; a stale or wrong value in mode.string_storage config.
Related errors
- Value must be one of python|pyarrow
- No such keys(s): {pat!r}
- {k} is not a valid identifier
- {k} is a python keyword
- Value must be an instance of {type_repr}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/45fcd0e8b0165258.
Report an issue: GitHub.