{"record":{"id":"42ae83cca7b04c15","repo":"apache/iceberg","slug":"unsupported-aggregate-type","errorCode":null,"errorMessage":"Unsupported aggregate type: ","messagePattern":"Unsupported aggregate type: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/BoundAggregate.java","lineNumber":93,"sourceCode":"    } else {\n      return ref().name();\n    }\n  }\n\n  public String describe() {\n    switch (op()) {\n      case COUNT_STAR:\n        return \"count(*)\";\n      case COUNT:\n        return \"count(\" + ExpressionUtil.describe(term()) + \")\";\n      case COUNT_NULL:\n        return \"count_if(\" + ExpressionUtil.describe(term()) + \" is null)\";\n      case MAX:\n        return \"max(\" + ExpressionUtil.describe(term()) + \")\";\n      case MIN:\n        return \"min(\" + ExpressionUtil.describe(term()) + \")\";\n      default:\n        throw new UnsupportedOperationException(\"Unsupported aggregate type: \" + op());\n    }\n  }\n\n  <V> boolean safeContainsKey(Map<Integer, V> map, int key) {\n    if (map == null) {\n      return false;\n    }\n    return map.containsKey(key);\n  }\n\n  <V> V safeGet(Map<Integer, V> map, int key) {\n    return safeGet(map, key, null);\n  }\n\n  <V> V safeGet(Map<Integer, V> map, int key, V defaultValue) {\n    if (map != null) {\n      return map.getOrDefault(key, defaultValue);\n    }","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/BoundAggregate.java#L75-L111","documentation":"BoundAggregate.describe() (and related string/eval switches) only recognizes COUNT, COUNT_IF, MAX, and MIN aggregate operations. Any other Operation reaching the switch hits the default branch and throws this UnsupportedOperationException.","triggerScenarios":"Constructing a BoundAggregate with an operation other than COUNT/COUNT_IF/MAX/MIN (e.g. SUM or a predicate operation) and evaluating or describing it; internal mis-binding that produces a bound aggregate for a non-aggregate operation.","commonSituations":"Custom ExpressionParser emitting aggregates with unsupported ops; user code building Expressions.aggregate with a wrong Operation enum; version skew where new ops lack describe/eval support.","solutions":["Use only COUNT, COUNT_IF, MAX, MIN operations in aggregate expressions","Validate the operation before constructing/binding the aggregate","Update Iceberg version if a newer aggregate op is required","Fix parser/visitor code that maps predicate operations to aggregates"],"exampleFix":"// before\nExpression agg = Expressions.aggregate(Operation.SUM, Expressions.column(\"x\")); // unsupported\n// after\nExpression agg = Expressions.aggregate(Operation.MAX, Expressions.column(\"x\"));","handlingStrategy":"validation","validationCode":"Preconditions.checkArgument(Set.of(Operation.COUNT, Operation.MAX, Operation.MIN).contains(op), \"Unsupported aggregate op: %s\", op);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict aggregates to COUNT/COUNT_IF/MAX/MIN","Validate ops when parsing user expressions","Keep Iceberg version current for new aggregate ops"],"tags":["expressions","aggregates","invalid-enum-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}