{"record":{"id":"a26c6f701e2d7209","repo":"apache/flink","slug":"the-merged-accumulator-must-be-averageaccumulator","errorCode":null,"errorMessage":"The merged accumulator must be AverageAccumulator.","messagePattern":"The merged accumulator must be AverageAccumulator\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/accumulators/AverageAccumulator.java","lineNumber":78,"sourceCode":"            return 0.0;\n        }\n        return this.sum / this.count;\n    }\n\n    @Override\n    public void resetLocal() {\n        this.count = 0;\n        this.sum = 0;\n    }\n\n    @Override\n    public void merge(Accumulator<Double, Double> other) {\n        if (other instanceof AverageAccumulator) {\n            AverageAccumulator avg = (AverageAccumulator) other;\n            this.count += avg.count;\n            this.sum += avg.sum;\n        } else {\n            throw new IllegalArgumentException(\n                    \"The merged accumulator must be AverageAccumulator.\");\n        }\n    }\n\n    @Override\n    public AverageAccumulator clone() {\n        AverageAccumulator average = new AverageAccumulator();\n        average.count = this.count;\n        average.sum = this.sum;\n        return average;\n    }\n\n    @Override\n    public String toString() {\n        return \"AverageAccumulator \" + this.getLocalValue() + \" for \" + this.count + \" elements\";\n    }\n}\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/accumulators/AverageAccumulator.java#L60-L96","documentation":"Thrown by AverageAccumulator.merge when the argument is not an AverageAccumulator. Flink calls merge() across subtask accumulators of the same name; if the other accumulator is a different type (e.g., a DoubleCounter or a custom accumulator), it cannot contribute the count+sum pair that AverageAccumulator needs to compute the mean, so it rejects the merge.","triggerScenarios":"An accumulator named the same as an AverageAccumulator but backed by a different accumulator class; calling avgAccumulator.merge(someOtherAccumulator) directly in user code.","commonSituations":"Name collision between an AverageAccumulator and another built-in/custom accumulator in the same job; migrating from a DoubleCounter to an AverageAccumulator without renaming.","solutions":["Ensure every accumulator that should merge with this AverageAccumulator is also an AverageAccumulator registered under the same name.","Avoid manual merge() calls; rely on the runtime to merge identically-named, identically-typed accumulators.","Rename colliding accumulators so each name maps to exactly one accumulator type."],"exampleFix":"// before\ngetRuntimeContext().getAverageAccumulator(\"stats\"); // op A\ngetRuntimeContext().getDoubleCounter(\"stats\");      // op B -> merge fails\n// after\ngetRuntimeContext().getAverageAccumulator(\"stats.avg\");\ngetRuntimeContext().getDoubleCounter(\"stats.sum\");","handlingStrategy":"type-guard","validationCode":"// ensure all merged accumulators under one name are AverageAccumulator\ngetRuntimeContext().getAverageAccumulator(\"stats.avg\");","typeGuard":"public static boolean isAverage(Accumulator<?,?> a) {\n    return a instanceof AverageAccumulator;\n}","tryCatchPattern":null,"preventionTips":["Avoid manual merge() calls; let the runtime merge same-named accumulators.","Namespace accumulator names per type.","Don't switch accumulator types under an existing name."],"tags":["accumulator","average","merge","type-mismatch"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}