{"record":{"id":"659b0608974ad657","repo":"pandas-dev/pandas","slug":"searchsorted-requires-array-to-be-sorted-which-is-659b06","errorCode":null,"errorMessage":"searchsorted requires array to be sorted, which is impossible with NAs present.","messagePattern":"searchsorted requires array to be sorted, which is impossible with NAs present\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":1440,"sourceCode":"\n        Returns\n        -------\n        array of ints or int\n            If value is array-like, array of insertion points.\n            If value is scalar, a single integer.\n\n        See Also\n        --------\n        numpy.searchsorted : Similar method from NumPy.\n\n        Examples\n        --------\n        >>> arr = pd.array([1, 2, 3, 5])\n        >>> arr.searchsorted([4])\n        array([3])\n        \"\"\"\n        if self._hasna:\n            raise ValueError(\n                \"searchsorted requires array to be sorted, which is impossible \"\n                \"with NAs present.\"\n            )\n        if isinstance(value, ExtensionArray):\n            value = value.astype(object)\n        # Base class searchsorted would cast to object, which is *much* slower.\n        return self._data.searchsorted(value, side=side, sorter=sorter)\n\n    def factorize(\n        self,\n        use_na_sentinel: bool = True,\n    ) -> tuple[np.ndarray, ExtensionArray]:\n        \"\"\"\n        Encode the extension array as an enumerated type.\n\n        Parameters\n        ----------\n        use_na_sentinel : bool, default True","sourceCodeStart":1422,"sourceCodeEnd":1458,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/masked.py#L1422-L1458","documentation":"Raised by BaseMaskedArray.searchsorted when the array contains missing values (self._hasna). searchsorted assumes a sorted array; with NAs present the array cannot be meaningfully ordered, so any insertion-point answer would be ill-defined. pandas refuses rather than returning a misleading index.","triggerScenarios":"Calling arr.searchsorted(v) or Series.searchsorted(v) on a nullable masked array that contains any NA.","commonSituations":"Using searchsorted for bisect-style lookups on a nullable numeric column that was not cleaned; assuming a sorted Int64 column is NA-free.","solutions":["Drop or fill NAs first: clean = arr[~arr.isna()]; clean.searchsorted(v).","Fill missing values while preserving order semantics if appropriate.","Use a non-nullable dtype and ensure no NaN, e.g. arr.astype('int64') after fillna."],"exampleFix":"// before\narr.searchsorted(5)  # raises if arr has NA\n\n// after\narr[~arr.isna()].searchsorted(5)","handlingStrategy":"validation","validationCode":"def searchsorted_safe(arr, v):\n    if getattr(arr, \"_hasna\", False):\n        raise ValueError(\"array has NA; drop/fill before searchsorted\")\n    return arr.searchsorted(v)","typeGuard":"def is_searchsortable(arr) -> bool:\n    return not getattr(arr, \"_hasna\", False)","tryCatchPattern":"try:\n    idx = arr.searchsorted(v)\nexcept ValueError as e:\n    if \"searchsorted\" in str(e) and \"NAs\" in str(e):\n        idx = arr[~arr.isna()].searchsorted(v)\n    else:\n        raise","preventionTips":["Guarantee NA-free sorted data before searchsorted.","Cache the NA-free sorted view if called in a loop.","Consider bisect on a plain int64 numpy array for hot paths."],"tags":["masked-array","searchsorted","missing-values","sorting"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}