pandas-dev/pandas · error · ValueError

searchsorted requires array to be sorted, which is impossibl

Error message

searchsorted requires array to be sorted, which is impossible with NAs present.

What it means

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.

Source

Thrown at pandas/core/arrays/masked.py:1440

        Returns
        -------
        array of ints or int
            If value is array-like, array of insertion points.
            If value is scalar, a single integer.

        See Also
        --------
        numpy.searchsorted : Similar method from NumPy.

        Examples
        --------
        >>> arr = pd.array([1, 2, 3, 5])
        >>> arr.searchsorted([4])
        array([3])
        """
        if self._hasna:
            raise ValueError(
                "searchsorted requires array to be sorted, which is impossible "
                "with NAs present."
            )
        if isinstance(value, ExtensionArray):
            value = value.astype(object)
        # Base class searchsorted would cast to object, which is *much* slower.
        return self._data.searchsorted(value, side=side, sorter=sorter)

    def factorize(
        self,
        use_na_sentinel: bool = True,
    ) -> tuple[np.ndarray, ExtensionArray]:
        """
        Encode the extension array as an enumerated type.

        Parameters
        ----------
        use_na_sentinel : bool, default True

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Drop or fill NAs first: clean = arr[~arr.isna()]; clean.searchsorted(v).
  2. Fill missing values while preserving order semantics if appropriate.
  3. Use a non-nullable dtype and ensure no NaN, e.g. arr.astype('int64') after fillna.

Example fix

// before
arr.searchsorted(5)  # raises if arr has NA

// after
arr[~arr.isna()].searchsorted(5)
Defensive patterns

Strategy: validation

Validate before calling

def searchsorted_safe(arr, v):
    if getattr(arr, "_hasna", False):
        raise ValueError("array has NA; drop/fill before searchsorted")
    return arr.searchsorted(v)

Type guard

def is_searchsortable(arr) -> bool:
    return not getattr(arr, "_hasna", False)

Try / catch

try:
    idx = arr.searchsorted(v)
except ValueError as e:
    if "searchsorted" in str(e) and "NAs" in str(e):
        idx = arr[~arr.isna()].searchsorted(v)
    else:
        raise

Prevention

When it happens

Trigger: Calling arr.searchsorted(v) or Series.searchsorted(v) on a nullable masked array that contains any NA.

Common situations: Using searchsorted for bisect-style lookups on a nullable numeric column that was not cleaned; assuming a sorted Int64 column is NA-free.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/659b0608974ad657. Report an issue: GitHub.