{"record":{"id":"12fa65dff5fea9c7","repo":"apache/druid","slug":"aggregatorfactorynotmergeableexception-12fa65","errorCode":null,"errorMessage":"AggregatorFactoryNotMergeableException","messagePattern":"AggregatorFactoryNotMergeableException","errorType":"exception","errorClass":"AggregatorFactoryNotMergeableException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/SimpleFloatAggregatorFactory.java","lineNumber":183,"sourceCode":"  {\n    return object;\n  }\n\n  @Override\n  public List<String> requiredFields()\n  {\n    return fieldName != null\n           ? Collections.singletonList(fieldName)\n           : fieldExpression.get().analyzeInputs().getRequiredBindingsList();\n  }\n\n  @Override\n  public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException\n  {\n    if (other.getName().equals(this.getName()) && this.getClass() == other.getClass()) {\n      return getCombiningFactory();\n    } else {\n      throw new AggregatorFactoryNotMergeableException(this, other);\n    }\n  }\n\n  @Override\n  public int hashCode()\n  {\n    return Objects.hash(fieldName, expression, name);\n  }\n\n  @Override\n  public boolean equals(Object o)\n  {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/SimpleFloatAggregatorFactory.java#L165-L201","documentation":"SimpleFloatAggregatorFactory.getMergingFactory throws AggregatorFactoryNotMergeableException when the other factory's name or class does not match this one. Druid merges partial results across segments only when both factories are the same class (float-based aggregators) and share the same output name. A mismatch means the query is asking to combine a float aggregation with something that cannot be combined into it.","triggerScenarios":"Calling getMergingFactory(other) with an other whose getName() differs from this factory's name, or whose class is not SimpleFloatAggregatorFactory (e.g. a double or long aggregator), typically during distributed query merging across multiple segments.","commonSituations":"Mixing float and double aggregators under one output name in a multi-segment query; schema changes between ingestion rounds that changed an aggregator's numeric type; subquery + outer query where the same name maps to different aggregator types.","solutions":["Align the output names of the float aggregators on both sides of the merge","Use the same aggregator class (floatSum/floatMin/floatMax etc.) on both sides","Adjust the query or ingestion spec so the same output name always refers to the same float-based aggregation","If schema drifted, re-run the query with explicit numeric casts or re-ingest data to a consistent type"],"exampleFix":"// before\n { type: \"floatSum\", name: \"s\" }  vs  { type: \"doubleSum\", name: \"s\" }\n// after\n { type: \"floatSum\", name: \"s\" }  on both shards / subquery and outer query","handlingStrategy":"validation","validationCode":"boolean mergeable(AggregatorFactory a, AggregatorFactory b) {\n  return a.getName().equals(b.getName()) && a.getClass() == b.getClass();\n}","typeGuard":"boolean isMergeableFloatPair(AggregatorFactory other, SimpleFloatAggregatorFactory self) {\n  return other instanceof SimpleFloatAggregatorFactory && other.getName().equals(self.getName());\n}","tryCatchPattern":"try {\n  AggregatorFactory merged = factory.getMergingFactory(other);\n} catch (AggregatorFactoryNotMergeableException e) {\n  LOGGER.warn(e, \"Non-mergeable float aggregators: %s vs %s\", e.getFactory1(), e.getFactory2());\n}","preventionTips":["Never reuse the same output name for aggregators of different numeric types","Keep float aggregators consistent between subquery and outer query layers","Validate ingestion schema changes for metric type drift (float -> double)","Run merge-sensitive queries against multi-segment datasources in tests"],"tags":["aggregation","mergeability","druid"],"backgroundTag":"aggregator-factory-not-mergeable","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}