{"record":{"id":"b3a9490e1491b545","repo":"apache/druid","slug":"there-can-only-be-one-aggregation-for-column-s","errorCode":null,"errorMessage":"There can only be one aggregation for column [%s].","messagePattern":"There can only be one aggregation for column \\[(.+?)\\]\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/SegmentGenerationUtils.java","lineNumber":363,"sourceCode":"    for (final KeyColumn clusterByColumn : queryClusterBy.getColumns()) {\n      final IntList outputColumns = columnMappings.getOutputColumnsForQueryColumn(clusterByColumn.columnName());\n      for (final int outputColumn : outputColumns) {\n        outputColumnsInOrder.add(columnMappings.getOutputColumnName(outputColumn));\n      }\n    }\n\n    // Then all other columns.\n    outputColumnsInOrder.addAll(columnMappings.getOutputColumnNames());\n\n    Map<String, AggregatorFactory> outputColumnAggregatorFactories = new HashMap<>();\n\n    if (isRollupQuery) {\n      // Populate aggregators from the native query when doing an ingest in rollup mode.\n      for (AggregatorFactory aggregatorFactory : ((GroupByQuery) query).getAggregatorSpecs()) {\n        for (final int outputColumn : columnMappings.getOutputColumnsForQueryColumn(aggregatorFactory.getName())) {\n          final String outputColumnName = columnMappings.getOutputColumnName(outputColumn);\n          if (outputColumnAggregatorFactories.containsKey(outputColumnName)) {\n            throw new ISE(\"There can only be one aggregation for column [%s].\", outputColumn);\n          } else {\n            outputColumnAggregatorFactories.put(\n                outputColumnName,\n                aggregatorFactory.withName(outputColumnName).getCombiningFactory()\n            );\n          }\n        }\n      }\n    }\n\n    // Each column can be either a dimension or an aggregator.\n    // For non-complex columns, If the aggregator factory of the column is not available, we treat the column as\n    // a dimension. For complex columns, certains hacks are in place.\n    for (final String outputColumnName : outputColumnsInOrder) {\n      // CollectionUtils.getOnlyElement because this method is only called during ingestion, where we require\n      // that output names be unique.\n      final int outputColumn = CollectionUtils.getOnlyElement(\n          columnMappings.getOutputColumnsByName(outputColumnName),","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/SegmentGenerationUtils.java#L345-L381","documentation":"Raised in SegmentGenerationUtils.makeDimensionsAndAggregatorsForIngestion when, for a rollup MSQ ingestion, an output column ends up with more than one AggregatorFactory. Each rollup output column must be produced by exactly one aggregator; duplicates indicate a corrupted columnMappings/aggregator mapping built from the query plan.","triggerScenarios":"Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/SegmentGenerationUtils.java:363 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check that the ingestion SQL does not alias the same aggregated expression to a column name that is aggregated again.","If this arises from an internally generated plan, file a bug with the query: the columnMappings → aggregator assignment should never produce duplicates.","Work around by renaming conflicting output columns in the SQL."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}