{"record":{"id":"6d5323ba95eb63db","repo":"apache/druid","slug":"aggregatorfactorynotmergeableexception-6d5323","errorCode":null,"errorMessage":"AggregatorFactoryNotMergeableException","messagePattern":"AggregatorFactoryNotMergeableException","errorType":"exception","errorClass":"AggregatorFactoryNotMergeableException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchAggregatorFactory.java","lineNumber":179,"sourceCode":"    }\n    TDigest union = (TDigest) lhs;\n    union.add((TDigest) rhs);\n    return union;\n  }\n\n  @Override\n  public AggregatorFactory getCombiningFactory()\n  {\n    return new TDigestSketchAggregatorFactory(name, name, compression, tDigestConfig);\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 Object deserialize(Object serializedSketch)\n  {\n    return TDigestSketchUtils.deserialize(serializedSketch);\n  }\n\n  @Nullable\n  @Override\n  public Object finalizeComputation(@Nullable Object object)\n  {\n    return object;\n  }\n\n  @Override\n  @JsonProperty","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchAggregatorFactory.java#L161-L197","documentation":"AggregatorFactory.getMergingFactory requires that the two factories merge into one: same name and same concrete class. TDDigestSketchAggregatorFactory throws AggregatorFactoryNotMergeableException when the other factory differs in name or class, meaning query-level merging cannot combine the two aggregations.","triggerScenarios":"Merging query results where sub-queries or the broker combine aggregator factories: one factory named differently (e.g. aliased output name) or of a different class (tdigest vs doubleSum) is passed to getMergingFactory.","commonSituations":"SQL planner producing mismatched aggregator aliases for the same underlying column; combining a tdigestsketch aggregator with another aggregator type on the same metric; distributed query merge across brokers with differing query specs.","solutions":["Ensure both aggregators share the same output name and the same factory class (both TDigestSketchAggregatorFactory) with identical parameters.","Fix the query so the tdigestsketch aggregator is not merged with an incompatible aggregator type; use separate output names for separate aggregations.","Align the SQL/native query specs across broker and historicals so the same factory is generated on each side.","If thrown from a custom extension, implement/verify getCombiningFactory for the pair."],"exampleFix":"// before\nAggregatorFactory a = new TDigestSketchAggregatorFactory(\"sk1\", \"col\", 100);\nAggregatorFactory b = new DoubleSumAggregatorFactory(\"sk1\", \"col\");\n// after\nAggregatorFactory a = new TDigestSketchAggregatorFactory(\"sk1\", \"col\", 100);\nAggregatorFactory b = new TDigestSketchAggregatorFactory(\"sk1\", \"col\", 100); // same name and type","handlingStrategy":"try-catch","validationCode":"if (!other.getName().equals(this.getName()) || other.getClass() != this.getClass()) { throw new IllegalArgumentException(\"aggregators not mergeable: \" + this + \" vs \" + other); }","typeGuard":null,"tryCatchPattern":"try { merged = factory.getMergingFactory(other); } catch (AggregatorFactoryNotMergeableException e) { log.error(\"Cannot merge aggregators %s and %s; check query aliases/types\", e); }","preventionTips":["Keep aggregator output names unique and consistent between broker and historicals.","Never merge aggregators of different classes on the same metric.","Align query specs so identical factories are generated on all nodes.","Give incompatible aggregations distinct output names."],"tags":["java","druid","tdigest","merge"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}