pandas-dev/pandas · error · ValueError
cannot assign mismatch length to masked array
Error message
cannot assign mismatch length to masked array
What it means
Raised by putmask_without_repeat (putmask.py:97) as a ValueError when a list-like `new` value is being applied through a boolean mask but its length matches neither the number of True positions in the mask nor the full length of the values array (nor 1). numpy's np.putmask would silently repeat/truncate, producing wrong results; pandas detects the length mismatch and refuses.
Source
Thrown at pandas/core/array_algos/putmask.py:97
# TODO: this prob needs some better checking for 2D cases
nlocs = mask.sum()
if nlocs > 0 and is_list_like(new) and getattr(new, "ndim", 1) == 1:
shape = np.shape(new)
# np.shape compat for if setitem_datetimelike_compat
# changed arraylike to list e.g. test_where_dt64_2d
if nlocs == shape[-1]:
# GH#30567
# If length of ``new`` is less than the length of ``values``,
# `np.putmask` would first repeat the ``new`` array and then
# assign the masked values hence produces incorrect result.
# `np.place` on the other hand uses the ``new`` values at it is
# to place in the masked locations of ``values``
np.place(values, mask, new)
# i.e. values[mask] = new
elif mask.shape[-1] == shape[-1] or shape[-1] == 1:
np.putmask(values, mask, new)
else:
raise ValueError("cannot assign mismatch length to masked array")
else:
np.putmask(values, mask, new)
def validate_putmask(
values: ArrayLike | MultiIndex, mask: np.ndarray
) -> tuple[npt.NDArray[np.bool_], bool]:
"""
Validate mask and check if this putmask operation is a no-op.
"""
mask = extract_bool_array(mask)
if mask.shape != values.shape:
raise ValueError("putmask: mask and data must be the same size")
noop = not mask.any()
return mask, noop
View on GitHub (pinned to 71959b8cb9)
Solutions
- Size `other` to match either the full array length or exactly the number of True positions in the mask.
- Pass a scalar instead of a list for a constant replacement: df.where(cond, other=0).
- Use df.mask(cond, other) with a same-shaped Series whose index aligns, so pandas can align positions correctly.
Example fix
// before s = pd.Series([1,2,3,4]) s.where([True,False,True,False], other=[99, 88]) # length 2 mismatches // after s.where([True,False,True,False], other=[99, 88, 99, 88]) # full length // or s.where([True,False,True,False], other=99) # scalar
Defensive patterns
Strategy: validation
Validate before calling
nlocs = int(np.asarray(mask).sum())
new_len = len(new) if hasattr(new, '__len__') else 1
if new_len not in (1, nlocs, len(values)):
raise ValueError(f'other has length {new_len}; expected 1, {nlocs}, or {len(values)}') Type guard
def putmask_other_compatible(values, mask, other) -> bool:
import numpy as np
nlocs = int(np.asarray(mask).sum())
if not hasattr(other, '__len__'):
return True
return len(other) in (1, nlocs, len(values)) Try / catch
try:
df.where(cond, other=other)
except ValueError as e:
if 'mismatch length' in str(e):
df.where(cond, other=0) # scalar fallback
else:
raise Prevention
- Size `other` to match the array or the number of True mask positions.
- Prefer a scalar replacement when the value is constant.
When it happens
Trigger: df.where(cond, other=[1,2,3]) or s.mask(cond, other) where len(other) is neither len(values), mask.sum(), nor 1. Hit at putmask.py:80-97 when nlocs > 0, new is 1-D, and nlocs != shape[-1] AND mask.shape[-1] != shape[-1] AND shape[-1] != 1.
Common situations: Passing a replacement list sized to a filtered subset rather than the full array; mismatched lengths after a reindex or filter; building `other` from value_counts().index or similar shape-changing ops; using a Series whose index doesn't align with the masked frame.
Related errors
- putmask: mask and data must be the same size
- cannot broadcast result
- name {self.name!r} is not defined
- arithmetic operations are not supported inside an HDFStore '
- Cannot compare {conv_val} of type {type(conv_val)} to {kind}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/980abcdc6acb0b73.
Report an issue: GitHub.