pandas-dev/pandas · error · ValueError
na_action must either be 'ignore' or None
Error message
na_action must either be 'ignore' or None, {na_action} was passed What it means
The map_array() function (which powers Series.map and similar) accepts an na_action parameter that controls how NaN values are handled: either None (pass NaN to the mapping function) or 'ignore' (propagate NaN without calling the function). Any other value for na_action is rejected with a ValueError. This is a strict API contract — there is no third option.
Solutions
- Use na_action='ignore' to skip NaN, or na_action=None to pass NaN to the function.
- Validate the na_action value before calling map: assert na_action in (None, 'ignore').
- If building a configurable wrapper, map user-friendly names to the valid values.
Example fix
# before s.map(my_func, na_action='skip') # after s.map(my_func, na_action='ignore')
Defensive patterns
Strategy: validation
Validate before calling
VALID_NA_ACTIONS = (None, 'ignore')
def safe_map(series, mapper, na_action=None):
if na_action not in VALID_NA_ACTIONS:
raise ValueError(f"na_action must be one of {VALID_NA_ACTIONS}, got {na_action!r}")
return series.map(mapper, na_action=na_action) Type guard
def is_valid_na_action(na_action) -> bool:
return na_action in (None, 'ignore') Try / catch
try:
result = s.map(func, na_action=na_action)
except ValueError as e:
if "na_action" in str(e):
result = s.map(func, na_action=None) # default
else:
raise Prevention
- Only use na_action='ignore' or na_action=None with Series.map.
- Do not confuse pandas' na_action with skipna parameters from other APIs.
- Validate na_action against the allowed set before passing it to map.
When it happens
Trigger: Calling s.map(func, na_action='skip') or s.map(func, na_action=True) — misspelling the valid value or passing a boolean. Passing na_action from a variable or config that was not validated. Using 'drop' or 'omit' instead of the correct 'ignore'.
Common situations: Confusing pandas' na_action='ignore' with other libraries' NaN-handling parameters (e.g., skipna=True). Copying code from a different API that uses different sentinel values. Passing a dynamically-sourced parameter without validating it.
Related errors
- invalid value for result_type, must be one of
- by_row= not allowed
- cannot broadcast result
- cannot combine transform and aggregation operations
- cannot diff on axis=
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/b6b4291b4dd48b76.
Report an issue: GitHub.
Appendix: 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 3b7651241d)