{"record":{"id":"d4c27a2a2202b24a","repo":"pandas-dev/pandas","slug":"cannot-pass-mask-for-booleanarray-input","errorCode":null,"errorMessage":"cannot pass mask for BooleanArray input","messagePattern":"cannot pass mask for BooleanArray input","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/boolean.py","lineNumber":201,"sourceCode":"    values, mask=None, copy: bool = False\n) -> tuple[np.ndarray, np.ndarray]:\n    \"\"\"\n    Coerce the input values array to numpy arrays with a mask.\n\n    Parameters\n    ----------\n    values : 1D list-like\n    mask : bool 1D array, optional\n    copy : bool, default False\n        if True, copy the input\n\n    Returns\n    -------\n    tuple of (values, mask)\n    \"\"\"\n    if isinstance(values, BooleanArray):\n        if mask is not None:\n            raise ValueError(\"cannot pass mask for BooleanArray input\")\n        values, mask = values._data, values._mask\n        if copy:\n            values = values.copy()\n            mask = mask.copy()\n        return values, mask\n\n    mask_values = None\n    if isinstance(values, np.ndarray) and values.dtype == np.bool_:\n        if copy:\n            values = values.copy()\n    elif isinstance(values, np.ndarray) and values.dtype.kind in \"iufcb\":\n        mask_values = isna(values)\n\n        values_bool = np.zeros(len(values), dtype=bool)\n        values_bool[~mask_values] = values[~mask_values].astype(bool)\n\n        if not np.all(\n            values_bool[~mask_values].astype(values.dtype) == values[~mask_values]","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/boolean.py#L183-L219","documentation":"coerce_to_array (boolean.py:201) refuses a separately-passed mask when the input `values` is already a BooleanArray, because the BooleanArray carries its own mask and combining two masks would be ambiguous. It raises ValueError to prevent silent data corruption.","triggerScenarios":"Calling pd.array(BooleanArray_instance, mask=...) or BooleanArray._from_sequence with both a BooleanArray and a mask; internal callers of coerce_to_array that pass an explicit mask alongside an already-masked array.","commonSituations":"Library/extension code that double-masks data; refactoring that passed the wrong object into a boolean coercion helper; constructing BooleanArray via low-level APIs instead of pd.array.","solutions":["Do not pass a mask when the input is already a BooleanArray; let its built-in mask be reused.","If you need a custom mask, extract the underlying data first: ba._data and pass that with your mask.","Use the high-level pd.array(values, dtype='boolean') constructor instead of low-level coerce_to_array.","Validate the input type before forwarding to coerce_to_array."],"exampleFix":"# before\nba = pd.array([True, False], dtype=\"boolean\")\ncoerce_to_array(ba, mask=my_mask)  # raises\n\n# after\ncoerce_to_array(ba._data, mask=my_mask)","handlingStrategy":"validation","validationCode":"def safe_coerce(values, mask=None):\n    from pandas.core.arrays.boolean import coerce_to_array, BooleanArray\n    if isinstance(values, BooleanArray) and mask is not None:\n        values = values._data\n    return coerce_to_array(values, mask=mask)","typeGuard":"def is_boolean_array(x) -> bool:\n    from pandas.core.arrays.boolean import BooleanArray\n    return isinstance(x, BooleanArray)","tryCatchPattern":"try:\n    v, m = coerce_to_array(values, mask=mask)\nexcept ValueError as e:\n    if \"cannot pass mask for BooleanArray input\" in str(e):\n        v, m = coerce_to_array(values._data, mask=mask)\n    else:\n        raise","preventionTips":["Do not pass a mask when input is already a BooleanArray","Use pd.array for high-level construction","Extract _data before combining masks"],"tags":["boolean","mask","coercion","api-misuse"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}