{"record":{"id":"32083ada175af0b4","repo":"pandas-dev/pandas","slug":"no-accumulation-for-func-implemented-on-basemask-32083a","errorCode":null,"errorMessage":"No accumulation for {func} implemented on BaseMaskedArray","messagePattern":"No accumulation for (.+?) implemented on BaseMaskedArray","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/array_algos/masked_accumulations.py","lineNumber":63,"sourceCode":"        dtype_info = np.iinfo(values.dtype.type)\n    elif values.dtype.kind == \"b\":\n        # Max value of bool is 1, but since we are setting into a boolean\n        # array, 255 is fine as well. Min value has to be 0 when setting\n        # into the boolean array.\n        dtype_info = np.iinfo(np.uint8)\n    else:\n        raise NotImplementedError(\n            f\"No masked accumulation defined for dtype {values.dtype.type}\"\n        )\n    try:\n        fill_value = {\n            np.cumprod: 1,\n            np.maximum.accumulate: dtype_info.min,\n            np.cumsum: 0,\n            np.minimum.accumulate: dtype_info.max,\n        }[func]\n    except KeyError as err:\n        raise NotImplementedError(\n            f\"No accumulation for {func} implemented on BaseMaskedArray\"\n        ) from err\n\n    values[mask] = fill_value\n\n    if not skipna:\n        mask = np.maximum.accumulate(mask)\n\n    values = func(values)\n    return values, mask\n\n\ndef cumsum(\n    values: np.ndarray, mask: npt.NDArray[np.bool_], *, skipna: bool = True\n) -> tuple[np.ndarray, npt.NDArray[np.bool_]]:\n    return _cum_func(np.cumsum, values, mask, skipna=skipna)\n\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/array_algos/masked_accumulations.py#L45-L81","documentation":"NotImplementedError raised in masked_accumulations when the func is not one of np.cumprod, np.maximum.accumulate, np.cumsum, np.minimum.accumulate. The fill-value lookup dict has no entry for the func, so it is rejected.","triggerScenarios":"Internal dispatch: routing an unsupported accumulation (e.g. np.cumprod on a path expecting something else, or a custom ufunc) through masked accumulations.","commonSituations":"Custom array code or third-party extension arrays that hand an unsupported accumulator to the masked path.","solutions":["Use a supported accumulation method (cumsum, cumprod, cummin, cummax).","Implement the accumulation in the calling code instead of relying on the masked dispatch."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import numpy as np\nSUPPORTED_FUNCS = {np.cumprod, np.maximum.accumulate, np.cumsum, np.minimum.accumulate}\ndef safe_accum(func, values):\n    if func not in SUPPORTED_FUNCS:\n        raise ValueError(f'{func.__name__} is not a supported masked accumulation')\n    return func(values)","typeGuard":null,"tryCatchPattern":"try:\n    func(values)\nexcept NotImplementedError as e:\n    if 'No accumulation for' in str(e):\n        np.cumsum(values)  # fall back to a supported accumulator\n    else:\n        raise","preventionTips":["Only route the four supported numpy accumulators through masked arrays.","For custom reductions, operate on the underlying numpy buffer directly."],"tags":["internal","accumulation","masked-array"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}