pandas-dev/pandas · error · ValueError
Cannot mask with non-boolean array containing NA / NaN value
Error message
Cannot mask with non-boolean array containing NA / NaN values
What it means
Raised in pandas/core/common.py:151 within the boolean-mask validation used by __getitem__/loc when a mask array of object dtype contains NA/NaN among non-boolean entries. The guard distinguishes a pure boolean mask (ok) from a mask that mixes booleans and NaN, which is ambiguous and cannot safely select rows.
Source
Thrown at pandas/core/common.py:151
See Also
--------
check_array_indexer : Check that `key` is a valid array to index,
and convert to an ndarray.
"""
if isinstance(
key,
(ABCSeries, np.ndarray, ABCIndex, ABCExtensionArray, ABCNumpyExtensionArray),
) and not isinstance(key, ABCMultiIndex):
if key.dtype == np.object_:
key_array = np.asarray(key)
if not lib.is_bool_array(key_array):
na_msg = "Cannot mask with non-boolean array containing NA / NaN values"
if lib.is_bool_array(key_array, skipna=True):
# Don't raise on e.g. ["A", "B", np.nan], see
# test_loc_getitem_list_of_labels_categoricalindex_with_na
raise ValueError(na_msg)
return False
return True
elif is_bool_dtype(key.dtype):
return True
elif isinstance(key, list):
# check if np.array(key).dtype would be bool
if len(key) > 0:
if type(key) is not list:
# GH#42461 cython will raise TypeError if we pass a subclass
key = list(key)
return lib.is_bool_list(key)
return False
def cast_scalar_indexer(val: Any) -> Any:
"""
Disallow indexing with a float key, even if that key is a round number.View on GitHub (pinned to 71959b8cb9)
Solutions
- Fill the mask's missing values before indexing: `df[mask.fillna(False)]` or `mask.astype('boolean').fillna(False)`.
- Use pandas nullable boolean dtype: convert with `.astype('boolean')` which has a native NA, then decide True/False explicitly.
- Recompute the mask so NaN compares to False: `df['x'].eq('a', fill_value=False)` or `df['x'].fillna('').eq('a')`.
Example fix
# before
mask = df['x'] == 'a' # object column -> NaN where x is NaN
df[mask]
# after
df[df['x'].fillna('').eq('a')] Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def clean_boolean_mask(mask):
arr = np.asarray(mask)
if arr.dtype == object or arr.dtype.kind == 'O':
return np.array([bool(x) if x is not np.nan else False for x in arr], dtype=bool)
return arr.astype(bool)
df[clean_boolean_mask(mask)] Type guard
import numpy as np
def is_clean_bool_mask(mask) -> bool:
arr = np.asarray(mask)
return arr.dtype == bool or (arr.dtype == object and not np.isnan(arr).any()) Try / catch
try:
sub = df[mask]
except ValueError as e:
if 'Cannot mask with non-boolean' in str(e):
mask = mask.fillna(False) if hasattr(mask, 'fillna') else mask
sub = df[mask]
else:
raise Prevention
- fillna(False) boolean masks derived from object/nullable columns before indexing.
- Use the nullable 'boolean' dtype for masks that may contain NA.
- Prefer .eq/.ne with fill_value to avoid NaN propagation in comparisons.
When it happens
Trigger: `df[mask]` or `df.loc[mask]` where `mask` is an object-dtype array/Series containing values like [True, False, np.nan, True]. Commonly arises from elementwise comparisons on object columns, or a Series of booleans with missing values, or a list with NaN.
Common situations: Comparing object/nullable columns producing NaN (e.g. `df['x'] == 'a'` where x has NaN), boolean masks built via `np.where` without a fillna, or masks derived from joins/groupby that introduce NaN alignment.
Related errors
- Value must be an instance of {type_repr}
- Value must be one of {pp_values}
- Value must be a nonnegative integer or None
- Value must be a callable
- check_like must be False if check_index is False
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/ac7c4422e6ba3d22.
Report an issue: GitHub.