{"record":{"id":"bbbdb6459915b04c","repo":"pandas-dev/pandas","slug":"mask-should-be-boolean-numpy-array-use-the-pd-ar","errorCode":null,"errorMessage":"mask should be boolean numpy array. Use the 'pd.array' function instead","messagePattern":"mask should be boolean numpy array\\. Use the 'pd\\.array' function instead","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":154,"sourceCode":"    \"\"\"\n\n    # our underlying data and mask are each ndarrays\n    _data: np.ndarray\n    _mask: npt.NDArray[np.bool_]\n\n    @classmethod\n    def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self:\n        result = BaseMaskedArray.__new__(cls)\n        result._data = values\n        result._mask = mask\n        return result\n\n    def __init__(\n        self, values: np.ndarray, mask: npt.NDArray[np.bool_], copy: bool = False\n    ) -> None:\n        # values is supposed to already be validated in the subclass\n        if not (isinstance(mask, np.ndarray) and mask.dtype == np.bool_):\n            raise TypeError(\n                \"mask should be boolean numpy array. Use \"\n                \"the 'pd.array' function instead\"\n            )\n        if values.shape != mask.shape:\n            raise ValueError(\"values.shape must match mask.shape\")\n\n        if copy:\n            values = values.copy()\n            mask = mask.copy()\n\n        self._data = values\n        self._mask = mask\n\n    @classmethod\n    def _from_sequence(cls, scalars, *, dtype=None, copy: bool = False) -> Self:\n        values, mask = cls._coerce_to_array(scalars, dtype=dtype, copy=copy)\n        return cls(values, mask)\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/masked.py#L136-L172","documentation":"Raised by BaseMaskedArray.__init__ when the 'mask' argument is not a numpy ndarray of dtype bool. Masked arrays (Int8/Int16/.../Float64/Boolean) require the mask to be a real np.bool_ ndarray; passing a Python list, a pandas Series, or an int8 mask is rejected. The message points users to pd.array(...) which constructs masked arrays correctly from raw values.","triggerScenarios":"Directly instantiating IntegerArray/BooleanArray/values with a Python list of booleans or a uint8 mask, instead of going through the public constructor.","commonSituations":"Third-party code subclassing or wrapping BaseMaskedArray; users hand-rolling masks from comparisons without converting to ndarray.","solutions":["Build the array via pd.array(values, dtype='Int64') rather than constructing the masked class directly.","If you must construct directly, convert the mask: mask = np.asarray(mask, dtype=bool).","Ensure mask is a numpy.ndarray before passing — isinstance(mask, np.ndarray) and mask.dtype == np.bool_."],"exampleFix":"# before\nfrom pandas.arrays import IntegerArray\nIntegerArray(data, [True, False, True])\n\n# after\npd.array([1, 2, pd.NA, 4], dtype='Int64')\n# or\nIntegerArray(data, np.array([True, False, True], dtype=bool))","handlingStrategy":"type-guard","validationCode":"def as_bool_ndarray(mask):\n    if isinstance(mask, np.ndarray) and mask.dtype == np.bool_:\n        return mask\n    return np.asarray(mask, dtype=bool)","typeGuard":"def is_bool_ndarray(mask) -> bool:\n    return isinstance(mask, np.ndarray) and mask.dtype == np.bool_","tryCatchPattern":null,"preventionTips":["Construct masked arrays via pd.array(...) instead of direct class instantiation.","Always convert masks with np.asarray(mask, dtype=bool).","Avoid passing Python lists or pandas Series as masks."],"tags":["masked-array","constructor","type-error"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}