pandas-dev/pandas · error · ValueError

na_action must either be 'ignore' or None, {na_action} was p

Error message

na_action must either be 'ignore' or None, {na_action} was passed

What it means

Raised by pandas.core.algorithms.map_values (used by Series.map/Index.map) when na_action is neither None nor the string 'ignore'. map only supports two NA-handling modes: propagate NaN (None) or skip NaN ('ignore'); any other value is rejected.

Source

Thrown at pandas/core/algorithms.py:1895

    ----------
    mapper : function, dict, or Series
        Mapping correspondence.
    na_action : {None, 'ignore'}, default None
        If 'ignore', propagate NA values, without passing them to the
        mapping correspondence.

    Returns
    -------
    Union[ndarray, Index, ExtensionArray]
        The output of the mapping function applied to the array.
        If the function returns a tuple with more than one element
        a MultiIndex will be returned.
    """
    from pandas import Index

    if na_action not in (None, "ignore"):
        msg = f"na_action must either be 'ignore' or None, {na_action} was passed"
        raise ValueError(msg)

    # we can fastpath dict/Series to an efficient map
    # as we know that we are not going to have to yield
    # python types
    if is_dict_like(mapper):
        if isinstance(mapper, dict) and hasattr(mapper, "__missing__"):
            # If a dictionary subclass defines a default value method,
            # convert mapper to a lookup function (GH #15999).
            dict_with_default = mapper
            mapper = lambda x: dict_with_default[
                np.nan if isinstance(x, float) and np.isnan(x) else x
            ]
        else:
            # Dictionary does not have a default. Thus it's safe to
            # convert to a Series for efficiency.
            # we specify the keys here to handle the
            # possibility that they are tuples

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use na_action='ignore' to skip NaN, or na_action=None to propagate them.
  2. If you need custom NA handling, filter/handle NaN before calling map.
  3. Validate na_action against {None, 'ignore'} at your boundary.

Example fix

# before
s.map(func, na_action='skip')
# after
s.map(func, na_action='ignore')
Defensive patterns

Strategy: validation

Validate before calling

def safe_map(s, mapper, na_action=None):
    if na_action not in (None, 'ignore'):
        raise ValueError("na_action must be None or 'ignore'")
    return s.map(mapper, na_action=na_action)

Type guard

def valid_na_action(na) -> bool:
    return na in (None, 'ignore')

Prevention

When it happens

Trigger: s.map(func, na_action='skip'), s.map(func, na_action=True), s.map(func, na_action=False), or any value other than None/'ignore'.

Common situations: Users coming from fillna/dropna APIs who assume na_action='skip'; passing booleans; typos like na_action='Ignor'; copy-pasting kwargs from a different function.

Related errors


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