pandas-dev/pandas · error · ValueError

Encountered an NA value with skipna=False

Error message

Encountered an NA value with skipna=False

What it means

Raised by ExtensionArray.argmin (and the analogous argmax) when `skipna=False` and the array contains any NA/missing value. With skipna=False, pandas refuses to silently return a meaningless index in the presence of NAs, so it raises ValueError. This is the base implementation used by all ExtensionArray subclasses that do not override argmin/argmax.

Source

Thrown at pandas/core/arrays/base.py:1152

        int

        See Also
        --------
        ExtensionArray.argmax : Return the index of the maximum value.

        Examples
        --------
        >>> arr = pd.array([3, 1, 2, 5, 4])
        >>> arr.argmin()
        np.int64(1)
        """
        # Implementer note: You have two places to override the behavior of
        # argmin.
        # 1. _values_for_argsort : construct the values used in nargminmax
        # 2. argmin itself : total control over sorting.
        validate_bool_kwarg(skipna, "skipna")
        if not skipna and self._hasna:
            raise ValueError("Encountered an NA value with skipna=False")
        return cast("int", nargminmax(self, "argmin"))

    def argmax(self, skipna: bool = True) -> int:
        """
        Return the index of maximum value.

        In case of multiple occurrences of the maximum value, the index
        corresponding to the first occurrence is returned.

        Parameters
        ----------
        skipna : bool, default True

        Returns
        -------
        int

        See Also

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use the default skipna=True to skip NAs: `s.argmin()`.
  2. Drop NA before computing: `s.dropna().argmin()` (note: index shifts).
  3. Pre-check for NA and decide: `if s.isna().any(): ... else: s.argmin(skipna=False)`.
  4. Fill NA with a sentinel that preserves intended ordering, then call argmin(skipna=False).

Example fix

# before
s = pd.Series([3, None, 1], dtype="Int64")
s.argmin(skipna=False)  # ValueError: Encountered an NA value with skipna=False

# after
s.argmin()                # skipna=True (default)
# or
if not s.isna().any():
    s.argmin(skipna=False)
Defensive patterns

Strategy: validation

Validate before calling

def safe_argmin(s, skipna=False):
    if not skipna and s.isna().any():
        raise ValueError("Array contains NA; pass skipna=True or dropna first")
    return s.argmin(skipna=skipna)

Type guard

def has_no_na(s) -> bool:
    return not bool(s.isna().any())

Try / catch

try:
    return s.argmin(skipna=False)
except ValueError as e:
    if "NA value with skipna=False" in str(e):
        return s.dropna().argmin()
    raise

Prevention

When it happens

Trigger: Calling `s.argmin(skipna=False)` / `s.argmax(skipna=False)` / `s.idxmin(skipna=False)` / `s.idxmax(skipna=False)` on a nullable extension array (Int64, Float64, string[pyarrow], etc.) that has any NA values.

Common situations: Nullable numeric columns in ETL where NA means 'unknown'; analytics dashboards computing argmin/argmax with explicit NA semantics; custom reduction pipelines that pass skipna through from user config.

Related errors


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