pandas-dev/pandas · error · ValueError

values.shape and mask.shape must match

Error message

values.shape and mask.shape must match

What it means

coerce_to_array (boolean.py:262) verifies that the computed values array and the mask array have identical shapes; if they differ it raises ValueError. Mismatched lengths would silently misalign data and missingness, which pandas refuses.

Source

Thrown at pandas/core/arrays/boolean.py:262

        ):
            raise TypeError("Need to pass bool-like values")

    if mask is None and mask_values is None:
        mask = np.zeros(values.shape, dtype=bool)
    elif mask is None:
        mask = mask_values
    elif isinstance(mask, np.ndarray) and mask.dtype == np.bool_:
        if mask_values is not None:
            mask = mask | mask_values
        elif copy:
            mask = mask.copy()
    else:
        mask = np.array(mask, dtype=bool)
        if mask_values is not None:
            mask = mask | mask_values

    if values.shape != mask.shape:
        raise ValueError("values.shape and mask.shape must match")

    return values, mask


@set_module("pandas.arrays")
class BooleanArray(BaseMaskedArray):
    """
    Array of boolean (True/False) data with missing values.

    This is a pandas Extension array for boolean data, under the hood
    represented by 2 numpy arrays: a boolean array with the data and
    a boolean array with the mask (True indicating missing).

    BooleanArray implements Kleene logic (sometimes called three-value
    logic) for logical operations. See :ref:`boolean.kleene` for more.

    To construct a BooleanArray from generic array-like input, use
    :func:`pandas.array` specifying ``dtype="boolean"`` (see examples

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Ensure mask is derived from the same values: mask = isna(values) so lengths always match.
  2. Validate len(values) == len(mask) before passing to coerce_to_array.
  3. Build via the high-level pd.array(values, dtype='boolean') to let pandas compute the mask.
  4. Realign/trim the mask to the values length explicitly and intentionally.

Example fix

# before
coerce_to_array([True, False, True], mask=[False, False])  # raises

# after
mask = np.zeros(3, dtype=bool)
coerce_to_array([True, False, True], mask=mask)
Defensive patterns

Strategy: validation

Validate before calling

def safe_coerce_with_mask(values, mask):
    import numpy as np
    values = np.asarray(values)
    mask = np.asarray(mask)
    if values.shape != mask.shape:
        raise ValueError(f"shape mismatch: {values.shape} vs {mask.shape}")
    return values, mask

Type guard

def shapes_match(values, mask) -> bool:
    import numpy as np
    return np.asarray(values).shape == np.asarray(mask).shape

Try / catch

try:
    v, m = coerce_to_array(values, mask=mask)
except ValueError as e:
    if "shape" in str(e) and "mask" in str(e):
        import numpy as np
        mask = np.zeros(len(values), dtype=bool)
        v, m = coerce_to_array(values, mask=mask)
    else:
        raise

Prevention

When it happens

Trigger: Calling coerce_to_array(values, mask=...) (or the BooleanArray constructor path) with a mask whose length differs from the values; internal callers that build a mask from a different-length index.

Common situations: Low-level library code that constructs a mask from a filtered/aggregate index; off-by-one bugs when deriving a mask from isna() on a subset; refactoring that decoupled values and mask construction.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/c762a3e7dc84f9f9. Report an issue: GitHub.