pandas-dev/pandas · error · TypeError
requires a Series, Index, ExtensionArray, np.ndarray or…
Error message
{func_name} requires a Series, Index, ExtensionArray, np.ndarray or NumpyExtensionArray got {type(values).__name__}. What it means
The _ensure_arraylike helper validates that inputs to pandas core algorithms (factorize, unique, value_counts, etc.) are one of the recognized array-like types: Series, Index, ExtensionArray, np.ndarray, or NumpyExtensionArray. If the value is none of these and the calling function is not the isin-targets path (which has its own coercion logic), a TypeError is raised naming the offending type. This guard (GH#52986) prevents opaque downstream failures by failing fast with a descriptive message.
Solutions
- Wrap the value in np.asarray() or pd.Series() before passing it to the algorithm function.
- If the value is a list, ensure it is actually a list and not a scalar — check type(value) and len(value).
- If using a custom container, subclass ExtensionArray or convert to np.ndarray via np.asarray(container).
- For generators/iterators, materialize them first: list(gen) or np.fromiter(gen).
Example fix
# before pd.factorize(my_dict) # after pd.factorize(np.asarray(my_values))
Defensive patterns
Strategy: validation
Validate before calling
from pandas.api.types import is_list_like
def ensure_arraylike_for_algo(values):
if not isinstance(values, (pd.Series, pd.Index, np.ndarray)):
if is_list_like(values):
values = np.asarray(values)
else:
raise TypeError(f"Expected array-like, got {type(values).__name__}")
return values Type guard
def is_pandas_arraylike(values) -> bool:
return isinstance(
values,
(pd.Series, pd.Index, pd.api.extensions.ExtensionArray, np.ndarray)
) Try / catch
try:
result = pd.factorize(values)
except TypeError as e:
if "requires a Series" in str(e):
values = np.asarray(values)
result = pd.factorize(values)
else:
raise Prevention
- Always convert Python lists, tuples, and generators to np.asarray() before passing to pandas algorithm functions.
- Use type hints (ArrayLike) to catch type mismatches at static-analysis time.
- Wrap user-provided inputs with np.asarray() as a defensive normalization step.
When it happens
Trigger: Passing a Python scalar, a plain dict, a set, a string, or a custom non-array-like object to a public or internal function that delegates to _ensure_arraylike — e.g., pd.factorize(42), pd.unique("hello"), or pd.Series.tolist()-style calls that inadvertently route a scalar into an algorithm path. Also triggered by passing a generator or iterator where an indexable array-like is required.
Common situations: Refactoring code that previously passed lists (which get coerced) to pass a different non-array-like type. Using a custom container class that does not subclass any recognized pandas/numpy type. Passing a single scalar where a 1-D sequence was intended (e.g., extracting one element instead of a column). Version upgrades where coercion was previously implicit but is now strict (GH#52986 tightened this).
Related errors
- only list-like objects are allowed to be passed to isin()…
- only list-like objects are allowed to be passed to isin()…
- Only list-like objects or None are allowed to be passed to…
- Only np.ndarray, ExtensionArray, and Index objects are…
- pd.api.extensions.take requires a numpy.ndarray…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/076ffe84b2c84aea.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/algorithms.py:239
# error: Incompatible return value type
# (got "ndarray[tuple[Any, ...], dtype[Any]]",
# expected "ExtensionArray")
return values.astype(dtype, copy=False) # type: ignore[return-value]
def _ensure_arraylike(values, func_name: str) -> ArrayLike:
"""
ensure that we are arraylike if not already
"""
if not isinstance(
values,
(ABCIndex, ABCSeries, ABCExtensionArray, np.ndarray, ABCNumpyExtensionArray),
):
# GH#52986
if func_name != "isin-targets":
# Make an exception for the comps argument in isin.
raise TypeError(
f"{func_name} requires a Series, Index, "
f"ExtensionArray, np.ndarray or NumpyExtensionArray "
f"got {type(values).__name__}."
)
inferred = lib.infer_dtype(values, skipna=False)
if inferred in ["mixed", "string", "mixed-integer"]:
# "mixed-integer" to ensure we do not cast ["ss", 42] to str GH#22160
if isinstance(values, tuple):
values = list(values)
values = construct_1d_object_array_from_listlike(values)
else:
values = np.asarray(values)
return values
_hashtables = {
"complex128": htable.Complex128HashTable,View on GitHub (pinned to 3b7651241d)