pandas-dev/pandas · error · ValueError

searchsorted requires array to be sorted, which is…

Error message

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

What it means

Raised by BaseMaskedArray.searchsorted when self._hasna is True. searchsorted requires a totally ordered array, but pandas NA has no ordering relative to the other values, so a sorted position for a search cannot be defined reliably; pandas raises instead of returning a misleading index.

Solutions

  1. Fill or drop NAs first: arr.dropna().searchsorted(value) or arr.fillna(limit).searchsorted(value).
  2. Use a non-nullable dtype with a sentinel that preserves sort order.
  3. Filter NAs out and keep a separate index map if original positions are needed.

Example fix

// before
arr = pd.array([1, None, 3, 5], dtype='Int64')
arr.searchsorted(4)   # raises
// after
arr.dropna().searchsorted(4)
Defensive patterns

Strategy: validation

Validate before calling

if arr._hasna:
    raise ValueError('Cannot searchsorted with NAs; drop or fill first')
idx = arr.searchsorted(value)

Type guard

def is_searchsortable(arr) -> bool:
    return not arr._hasna

Try / catch

try:
    idx = arr.searchsorted(value)
except ValueError as e:
    if 'sorted' in str(e) and 'NAs' in str(e):
        idx = arr.dropna().searchsorted(value)
    else:
        raise

Prevention

When it happens

Trigger: Calling arr.searchsorted(value) on a nullable masked ExtensionArray (Int64, Float64) that contains at least one missing value (mask bit set).

Common situations: Running bisect-style lookups on a nullable column that still has NAs; using searchsorted on a sorted-but-not-yet-filled Series for index alignment; binary-search optimizations on dirty data.

Related errors


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

Appendix: 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 3b7651241d)