{"record":{"id":"980abcdc6acb0b73","repo":"pandas-dev/pandas","slug":"cannot-assign-mismatch-length-to-masked-array","errorCode":null,"errorMessage":"cannot assign mismatch length to masked array","messagePattern":"cannot assign mismatch length to masked array","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/array_algos/putmask.py","lineNumber":97,"sourceCode":"    # TODO: this prob needs some better checking for 2D cases\n    nlocs = mask.sum()\n    if nlocs > 0 and is_list_like(new) and getattr(new, \"ndim\", 1) == 1:\n        shape = np.shape(new)\n        # np.shape compat for if setitem_datetimelike_compat\n        #  changed arraylike to list e.g. test_where_dt64_2d\n        if nlocs == shape[-1]:\n            # GH#30567\n            # If length of ``new`` is less than the length of ``values``,\n            # `np.putmask` would first repeat the ``new`` array and then\n            # assign the masked values hence produces incorrect result.\n            # `np.place` on the other hand uses the ``new`` values at it is\n            # to place in the masked locations of ``values``\n            np.place(values, mask, new)\n            # i.e. values[mask] = new\n        elif mask.shape[-1] == shape[-1] or shape[-1] == 1:\n            np.putmask(values, mask, new)\n        else:\n            raise ValueError(\"cannot assign mismatch length to masked array\")\n    else:\n        np.putmask(values, mask, new)\n\n\ndef validate_putmask(\n    values: ArrayLike | MultiIndex, mask: np.ndarray\n) -> tuple[npt.NDArray[np.bool_], bool]:\n    \"\"\"\n    Validate mask and check if this putmask operation is a no-op.\n    \"\"\"\n    mask = extract_bool_array(mask)\n    if mask.shape != values.shape:\n        raise ValueError(\"putmask: mask and data must be the same size\")\n\n    noop = not mask.any()\n    return mask, noop\n\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/array_algos/putmask.py#L79-L115","documentation":"ValueError raised in putmask (masked assignment) when the new values array cannot be broadcast against the mask locations: the number of mask-true entries does not match the last-axis length of new, and neither the mask nor new is length-1 to allow putmask. pandas refuses to silently repeat or truncate values.","triggerScenarios":"df.where(mask, replacements) / df.mask(mask, replacements) / DataFrame.iloc assignment where replacements length != number of True cells; Series.replace via putmask with a mis-sized value array.","commonSituations":"Building a replacement array from a filtered subset without matching it to the number of masked positions; assigning list/Series values whose length matches the frame but not the mask.","solutions":["Make the replacement scalar so it broadcasts: df.where(mask, 0).","Size replacements to the number of True cells: replacements = replacements[mask.values].","Align the replacement to the frame's full shape and let putmask broadcast."],"exampleFix":"# before\ndf.where(mask, repl_array)  # len(repl_array) != mask.sum()\n# after\ndf.where(mask, repl_array[mask.to_numpy()])","handlingStrategy":"validation","validationCode":"def safe_where(df, mask, replacements):\n    import numpy as np\n    if not np.isscalar(replacements):\n        n_true = int(mask.to_numpy().sum()) if hasattr(mask, 'to_numpy') else int(np.count_nonzero(mask))\n        if len(replacements) != n_true:\n            raise ValueError(f'replacements length {len(replacements)} != mask true count {n_true}')\n    return df.where(mask, replacements)","typeGuard":null,"tryCatchPattern":"try:\n    df.where(mask, replacements)\nexcept ValueError as e:\n    if 'mismatch length' in str(e):\n        df.where(mask, replacements[mask.to_numpy()])  # align to true cells\n    else:\n        raise","preventionTips":["Use scalar replacements whenever possible to let broadcasting handle sizing.","When passing arrays, size them to mask.sum() exactly."],"tags":["putmask","where","masked-array","shape-mismatch"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}