pandas-dev/pandas · error · ValueError

Lengths must match

Error message

Lengths must match

What it means

Raised by BooleanArray's bitwise logical operators (_arithmethod) when a non-scalar operand's length differs from the array's length. Pandas requires element-wise logical ops (& | ^) between a BooleanArray (nullable 'boolean' dtype) and a list-like to be broadcastable to the same length, unlike scalars which broadcast freely.

Source

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

                    Pandas4Warning,
                    stacklevel=find_stack_level(),
                )

            other = np.asarray(other, dtype="bool")
            if other.ndim > 1:
                return NotImplemented
            other, mask = coerce_to_array(other, copy=False)
        elif isinstance(other, np.bool_):
            other = other.item()

        if other_is_scalar and other is not libmissing.NA and not lib.is_bool(other):
            raise TypeError(
                "'other' should be pandas.NA or a bool. "
                f"Got {type(other).__name__} instead."
            )

        if not other_is_scalar and len(self) != len(other):
            raise ValueError("Lengths must match")

        if op.__name__ in {"or_", "ror_"}:
            result, mask = ops.kleene_or(self._data, other, self._mask, mask)
        elif op.__name__ in {"and_", "rand_"}:
            result, mask = ops.kleene_and(self._data, other, self._mask, mask)
        else:
            # i.e. xor, rxor
            result, mask = ops.kleene_xor(self._data, other, self._mask, mask)

        # i.e. BooleanArray
        return self._maybe_mask_result(result, mask)

    def _accumulate(
        self, name: str, *, skipna: bool = True, **kwargs
    ) -> BaseMaskedArray:
        data = self._data
        mask = self._mask
        if name in ("cummin", "cummax"):

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Verify len(other) == len(mask_arr) before the operation and trim/reindex `other` to match.
  2. If comparing against a single value, pass a scalar (True/False/pd.NA) instead of a 1-element list so it broadcasts.
  3. Align via the DataFrame index: `mask_arr & df['other_col']` rather than `mask_arr & df['other_col'].tolist()` after row filtering.
  4. Use numpy arrays of equal length constructed from the same source to guarantee alignment.

Example fix

// before
m = pd.array([True, False, True], dtype="boolean")
out = m & [True, False]
// after
m = pd.array([True, False, True], dtype="boolean")
out = m & [True, False, True]
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def safe_bool_and(arr, other):
    other = np.asarray(other, dtype=bool) if not np.isscalar(other) else other
    if not np.isscalar(other) and len(other) != len(arr):
        raise ValueError(f"length {len(other)} != {len(arr)}")
    return arr & other

Type guard

def is_bool_array_of_len(x, n) -> bool:
    import pandas as pd
    return isinstance(x, (pd.array,)) and getattr(x, 'dtype', None) == 'boolean' or hasattr(x, '__len__') and len(x) == n

Try / catch

try:
    result = mask_arr & other
except ValueError as e:
    if 'Lengths must match' in str(e):
        raise ValueError(f"align other to len {len(mask_arr)}") from e
    raise

Prevention

When it happens

Trigger: Calling `mask_arr & other`, `mask_arr | other`, or `mask_arr ^ other` where `mask_arr` is a pandas BooleanArray and `other` is a list/ndarray/Series whose len() != len(mask_arr). For example `pd.array([True, False, True], dtype='boolean') & [True, False]`.

Common situations: Mistakenly pairing a boolean mask column with a differently-sized list after filtering rows, dropping NaNs, or reindexing; or feeding a Python list of bools that was built independently of the DataFrame column length.

Related errors


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