{"record":{"id":"21ab38c9faba4ca3","repo":"apache/druid","slug":"can-t-merge-s-s-and-s-s-with-detaile","errorCode":null,"errorMessage":"can't merge [%s : %s] and [%s : %s] , with detailed info [%s] and [%s]","messagePattern":"can't merge \\[(.+?) : (.+?)\\] and \\[(.+?) : (.+?)\\] , with detailed info \\[(.+?)\\] and \\[(.+?)\\]","errorType":"exception","errorClass":"AggregatorFactoryNotMergeableException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/AggregatorFactory.java","lineNumber":194,"sourceCode":"   * by the \"other\" aggregator factory, and we want to do some additional combining of them. This happens, for example,\n   * when compacting two segments together that both have a metric column with the same name. (Even though the name of\n   * the column is the same, the aggregator factory used to create it may be different from segment to segment.)\n   *\n   * This method may throw {@link AggregatorFactoryNotMergeableException}, meaning that \"this\" and \"other\" are not\n   * compatible and values from one cannot sensibly be combined with values from the other.\n   *\n   * @return a new Factory that can be used for merging the output of aggregators from this factory and other.\n   *\n   * @see #getCombiningFactory() which is equivalent to {@code foo.getMergingFactory(foo)} (when \"this\" and \"other\"\n   * are the same instance).\n   */\n  public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException\n  {\n    final AggregatorFactory combiningFactory = this.getCombiningFactory();\n    if (other.getName().equals(this.getName()) && combiningFactory.equals(other.getCombiningFactory())) {\n      return combiningFactory;\n    } else {\n      throw new AggregatorFactoryNotMergeableException(this, other);\n    }\n  }\n\n  /**\n   * This was previously used by group-by v1 and will be removed in a future release\n   */\n  @Deprecated\n  public List<AggregatorFactory> getRequiredColumns()\n  {\n    throw new UnsupportedOperationException(\n        \"Do not call or implement this method, it is deprecated and will be removed in a future releases.\"\n    );\n  }\n\n  /**\n   * A method that knows how to \"deserialize\" the object from whatever form it might have been put into\n   * in order to transfer via JSON.\n   *","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/AggregatorFactory.java#L176-L212","documentation":"getMergingFactory() merges two AggregatorFactory instances only when they have the same output name and equal combining factories. If the names differ or the combining factories are not equal, it throws AggregatorFactoryNotMergeableException, indicating pre-aggregated inputs cannot be merged under one aggregator spec.","triggerScenarios":"Calling getMergingFactory(other) where other.getName() differs from this.getName(), or where this.getCombiningFactory() does not equal other.getCombiningFactory() (different aggregator types, different fieldNames, expressions, or parameters).","commonSituations":"Merging segments/datasources whose schemas declare different aggregators under the same output name; typos in fieldName or different aggregators (doubleSum vs longSum) across datasources; subquery/post-aggregation name mismatches.","solutions":["Ensure both aggregator factories share the same output name and identical combining parameters (type, fieldName/expression)","Inspect the detailed info in the exception message to find the mismatched attribute and align the two specs","Adjust the query or ingestion spec so all merged sources use compatible aggregators"],"exampleFix":"// before\nnew DoubleSumAggregatorFactory(\"sum\", \"col1\") merged with new DoubleSumAggregatorFactory(\"sum\", \"col2\")\n// after\nnew DoubleSumAggregatorFactory(\"sum\", \"col\") merged with new DoubleSumAggregatorFactory(\"sum\", \"col\")","handlingStrategy":"validation","validationCode":"// before merging\nif (!a.getName().equals(b.getName()) || !a.getCombiningFactory().equals(b.getCombiningFactory())) {\n  throw new IllegalArgumentException(\"Aggregators not mergeable: \" + a.getName() + \" vs \" + b.getName());\n}","typeGuard":"boolean mergeable(AggregatorFactory a, AggregatorFactory b) {\n  return a.getName().equals(b.getName()) && a.getCombiningFactory().equals(b.getCombiningFactory());\n}","tryCatchPattern":"try {\n  merged = factory.getMergingFactory(other);\n} catch (AggregatorFactoryNotMergeableException e) {\n  log.error(\"Cannot merge aggregators\", e);\n  throw new IAE(\"Align aggregator names and parameters across datasources\");\n}","preventionTips":["Keep aggregator output names and parameters identical across datasources you plan to merge","Compare combining factories when composing multi-datasource schemas","Review 'detailed info' in the exception to locate the mismatched attribute"],"tags":["aggregation","merge","schema-mismatch"],"backgroundTag":"incompatible-source-type","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"}