{"record":{"id":"076ffe84b2c84aea","repo":"pandas-dev/pandas","slug":"func-name-requires-a-series-index-extensionarr","errorCode":null,"errorMessage":"{func_name} requires a Series, Index, ExtensionArray, np.ndarray or NumpyExtensionArray got {type(values).__name__}.","messagePattern":"(.+?) requires a Series, Index, ExtensionArray, np\\.ndarray or NumpyExtensionArray got (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/algorithms.py","lineNumber":239,"sourceCode":"\n    # error: Incompatible return value type\n    # (got \"ndarray[tuple[Any, ...], dtype[Any]]\",\n    # expected \"ExtensionArray\")\n    return values.astype(dtype, copy=False)  # type: ignore[return-value]\n\n\ndef _ensure_arraylike(values, func_name: str) -> ArrayLike:\n    \"\"\"\n    ensure that we are arraylike if not already\n    \"\"\"\n    if not isinstance(\n        values,\n        (ABCIndex, ABCSeries, ABCExtensionArray, np.ndarray, ABCNumpyExtensionArray),\n    ):\n        # GH#52986\n        if func_name != \"isin-targets\":\n            # Make an exception for the comps argument in isin.\n            raise TypeError(\n                f\"{func_name} requires a Series, Index, \"\n                f\"ExtensionArray, np.ndarray or NumpyExtensionArray \"\n                f\"got {type(values).__name__}.\"\n            )\n\n        inferred = lib.infer_dtype(values, skipna=False)\n        if inferred in [\"mixed\", \"string\", \"mixed-integer\"]:\n            # \"mixed-integer\" to ensure we do not cast [\"ss\", 42] to str GH#22160\n            if isinstance(values, tuple):\n                values = list(values)\n            values = construct_1d_object_array_from_listlike(values)\n        else:\n            values = np.asarray(values)\n    return values\n\n\n_hashtables = {\n    \"complex128\": htable.Complex128HashTable,","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/algorithms.py#L221-L257","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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)."],"exampleFix":"# before\npd.factorize(my_dict)\n\n# after\npd.factorize(np.asarray(my_values))","handlingStrategy":"validation","validationCode":"from pandas.api.types import is_list_like\n\ndef ensure_arraylike_for_algo(values):\n    if not isinstance(values, (pd.Series, pd.Index, np.ndarray)):\n        if is_list_like(values):\n            values = np.asarray(values)\n        else:\n            raise TypeError(f\"Expected array-like, got {type(values).__name__}\")\n    return values","typeGuard":"def is_pandas_arraylike(values) -> bool:\n    return isinstance(\n        values,\n        (pd.Series, pd.Index, pd.api.extensions.ExtensionArray, np.ndarray)\n    )","tryCatchPattern":"try:\n    result = pd.factorize(values)\nexcept TypeError as e:\n    if \"requires a Series\" in str(e):\n        values = np.asarray(values)\n        result = pd.factorize(values)\n    else:\n        raise","preventionTips":["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."],"tags":["pandas","algorithms","type-validation","typeerror","array-like"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}