{"record":{"id":"39fed36a32d7513c","repo":"apache/druid","slug":"only-one-of-fieldname-and-fieldexpression-should-b","errorCode":null,"errorMessage":"Only one of fieldName and fieldExpression should be non-null","messagePattern":"Only one of fieldName and fieldExpression should be non-null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/AggregatorUtil.java","lineNumber":304,"sourceCode":"          inspector.visit(\"baseSelector\", baseSelector);\n        }\n      }\n      return new ExpressionFloatColumnSelector();\n    }\n  }\n\n  /**\n   * Only one of fieldName and fieldExpression should be non-null\n   */\n  static ColumnValueSelector<?> makeColumnValueSelectorWithLongDefault(\n      final ColumnSelectorFactory columnSelectorFactory,\n      @Nullable final String fieldName,\n      @Nullable final Expr fieldExpression,\n      final long nullValue\n  )\n  {\n    if ((fieldName == null) == (fieldExpression == null)) {\n      throw new IllegalArgumentException(\"Only one of fieldName and fieldExpression should be non-null\");\n    }\n    if (fieldName != null) {\n      return columnSelectorFactory.makeColumnValueSelector(fieldName);\n    } else {\n      final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(\n          columnSelectorFactory,\n          fieldExpression\n      );\n      class ExpressionLongColumnSelector implements LongColumnSelector\n      {\n        @Override\n        public long getLong()\n        {\n          final ExprEval<?> exprEval = baseSelector.getObject();\n          return exprEval.isNumericNull() ? nullValue : exprEval.asLong();\n        }\n\n        @Override","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/AggregatorUtil.java#L286-L322","documentation":"Same mutual-exclusion rule as the float variant but for long-defaulting selectors: exactly one of fieldName or fieldExpression must be non-null when calling makeColumnValueSelectorWithLongDefault; otherwise IllegalArgumentException is thrown.","triggerScenarios":"Calling makeColumnValueSelectorWithLongDefault with both fieldName and fieldExpression set, or with neither set.","commonSituations":"Ingestion/query spec mistakes with both 'fieldName' and 'expression' keys present (or both absent) in long aggregators; programmatic factory construction errors.","solutions":["Supply exactly one of fieldName or fieldExpression","Remove the extra key from the JSON spec when both are present","Set the missing field when both are null"],"exampleFix":"// before\n{\"type\":\"longSum\",\"name\":\"l\",\"fieldName\":\"col\",\"expression\":\"col + 1\"}\n// after\n{\"type\":\"longSum\",\"name\":\"l\",\"fieldName\":\"col\"}","handlingStrategy":"validation","validationCode":"// before construction\nif ((fieldName == null) == (fieldExpression == null)) {\n  throw new IllegalArgumentException(\"Exactly one of fieldName or fieldExpression must be set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  selector = AggregatorUtil.makeColumnValueSelectorWithLongDefault(sf, fieldName, expr, 0L);\n} catch (IllegalArgumentException e) {\n  log.error(\"Bad long aggregator spec\", e);\n  throw e;\n}","preventionTips":["Audit long aggregator specs for both/neither fieldName and expression","Use schema validation on ingestion specs before deploying tasks","Keep expression usage in dedicated aggregators (e.g. expression 'longSum' variants) explicit"],"tags":["aggregation","validation","druid"],"backgroundTag":"mutually-exclusive-options","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"}