{"record":{"id":"ac7c4422e6ba3d22","repo":"pandas-dev/pandas","slug":"cannot-mask-with-non-boolean-array-containing-na","errorCode":null,"errorMessage":"Cannot mask with non-boolean array containing NA / NaN values","messagePattern":"Cannot mask with non-boolean array containing NA / NaN values","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/common.py","lineNumber":151,"sourceCode":"\n    See Also\n    --------\n    check_array_indexer : Check that `key` is a valid array to index,\n        and convert to an ndarray.\n    \"\"\"\n    if isinstance(\n        key,\n        (ABCSeries, np.ndarray, ABCIndex, ABCExtensionArray, ABCNumpyExtensionArray),\n    ) and not isinstance(key, ABCMultiIndex):\n        if key.dtype == np.object_:\n            key_array = np.asarray(key)\n\n            if not lib.is_bool_array(key_array):\n                na_msg = \"Cannot mask with non-boolean array containing NA / NaN values\"\n                if lib.is_bool_array(key_array, skipna=True):\n                    # Don't raise on e.g. [\"A\", \"B\", np.nan], see\n                    #  test_loc_getitem_list_of_labels_categoricalindex_with_na\n                    raise ValueError(na_msg)\n                return False\n            return True\n        elif is_bool_dtype(key.dtype):\n            return True\n    elif isinstance(key, list):\n        # check if np.array(key).dtype would be bool\n        if len(key) > 0:\n            if type(key) is not list:\n                # GH#42461 cython will raise TypeError if we pass a subclass\n                key = list(key)\n            return lib.is_bool_list(key)\n\n    return False\n\n\ndef cast_scalar_indexer(val: Any) -> Any:\n    \"\"\"\n    Disallow indexing with a float key, even if that key is a round number.","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/common.py#L133-L169","documentation":"Raised by is_bool_indexer when the key is an object-dtype array (or Series/Index/EA) that lib.is_bool_array reports as bool-with-skipna but not strict bool — i.e. it contains True/False plus NA/NaN. Object arrays of pure non-bool values (e.g. strings) are rejected by returning False (caller treats as label list), but a bool array containing NaN is ambiguous between mask and label semantics, so pandas raises ValueError. The guard exists because boolean masks with NaN cause silent row-dropping in the past.","triggerScenarios":"df.loc[pd.Series([True, False, np.nan])]; df[df['flag'].where(df['flag'].notna())]; a column with dtype object holding bools and None; masking after an operation that introduced NaN (e.g. .where(cond) with no fill).","commonSituations":"Reading Excel/CSV where a boolean column became object dtype with blanks; chained comparisons that yield NaN; user-built masks mixing bool and None; nullable pyarrow-backed bool arrays that landed in object dtype.","solutions":["Fill NA explicitly: mask = mask.fillna(False) or mask = mask.astype('boolean').fillna(False).","Use nullable boolean dtype: df['flag'].astype('boolean').","Drop NA before masking: df = df[df['flag'].notna()]; df = df[mask].","Rebuild the mask with a strict comparison that cannot produce NaN."],"exampleFix":"// before\nmask = pd.Series([True, False, None])\nout = df.loc[mask]\n// after\nmask = pd.Series([True, False, None]).astype('boolean').fillna(False)\nout = df.loc[mask]","handlingStrategy":"validation","validationCode":"mask = pd.Series(mask_array)\nif mask.dtype == object:\n    mask = mask.astype('boolean').fillna(False)\nout = df.loc[mask]","typeGuard":"def is_clean_bool_mask(mask) -> bool:\n    import numpy as np\n    s = pd.Series(mask) if not isinstance(mask, pd.Series) else mask\n    if s.dtype == object:\n        s = s.astype('boolean')\n    return s.notna().all() and pd.api.types.is_bool_dtype(s)","tryCatchPattern":null,"preventionTips":["Prefer 'boolean' nullable dtype for masks.","fillna(False) any mask before .loc indexing.","Avoid object dtype for boolean columns; convert at load time."],"tags":["value-error","boolean-mask","nan","loc","object-dtype","indexing"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}