{"record":{"id":"04750f186816041c","repo":"apache/druid","slug":"unknown-scale-metric","errorCode":null,"errorMessage":"Unknown scale metric","messagePattern":"Unknown scale metric","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/indexing/overlord/supervisor/autoscaler/LagStats.java","lineNumber":76,"sourceCode":"   * The preferred scaling metric that supervisor may specify to be used.\n   * This could be overrided by the autscaler.\n   */\n  public AggregateFunction getAggregateForScaling()\n  {\n    return aggregateForScaling;\n  }\n\n  public long getMetric(AggregateFunction metric)\n  {\n    switch (metric) {\n      case MAX:\n        return getMaxLag();\n      case SUM:\n        return getTotalLag();\n      case AVERAGE:\n        return getAvgLag();\n    }\n    throw new IllegalStateException(\"Unknown scale metric\");\n  }\n}\n","sourceCodeStart":58,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/indexing/overlord/supervisor/autoscaler/LagStats.java#L58-L79","documentation":"LagStats.getMetric resolves a ScaleMetric enum (MIN/MAX/SUM/AVERAGE) to its corresponding lag value. If the switch falls through with no matching case, the code assumes an unknown enum value was supplied and throws IllegalStateException('Unknown scale metric'). This guards against future enum values added without updating this method.","triggerScenarios":"Calling LagStats.getMetric with a ScaleMetric value not covered by the switch (MIN, MAX, SUM, AVERAGE), typically a newly added enum constant or an arbitrary/untrusted value.","commonSituations":"A Druid version upgrade introduces a new ScaleMetric constant while custom autoscaler code compiled against the old LagStats switch is still deployed; or reflective/serialized deserialization of a stale ScaleMetric value.","solutions":["Regenerate/recompile all code against the current Druid version so the switch covers every ScaleMetric constant","Add a case (or default fallback) in LagStats.getMetric for the missing ScaleMetric value","Log and inspect the offending metric value to identify where the stale enum comes from"],"exampleFix":"// before\nreturn switch (metric) { case MIN -> getMinLag(); case MAX -> getMaxLag(); case SUM -> getTotalLag(); case AVERAGE -> getAvgLag(); };\n// after\nreturn switch (metric) { case MIN -> getMinLag(); case MAX -> getMaxLag(); case SUM -> getTotalLag(); case AVERAGE -> getAvgLag(); case NEW_METRIC -> getNewMetricValue(); };","handlingStrategy":"validation","validationCode":"if (!EnumSet.of(ScaleMetric.MIN, ScaleMetric.MAX, ScaleMetric.SUM, ScaleMetric.AVERAGE).contains(metric)) { throw new IllegalArgumentException(\"Unsupported scale metric: \" + metric); }","typeGuard":null,"tryCatchPattern":"try { lag = lagStats.getMetric(metric); } catch (IllegalStateException e) { log.warn(e, \"Unknown scale metric %s, defaulting to MAX\", metric); lag = lagStats.getMaxLag(); }","preventionTips":["Recompile against the same Druid version as the runtime when using ScaleMetric","Add a switch exhaustiveness check (no default) so the compiler flags missing cases","Cover every ScaleMetric constant in unit tests"],"tags":["java","autoscaler","enum","internal-invariant"],"backgroundTag":"invalid-enum-value","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"}