{"record":{"id":"fcea13b82898d470","repo":"apache/druid","slug":"cannot-return-double-for-null-value-fcea13","errorCode":null,"errorMessage":"Cannot return double for Null Value","messagePattern":"Cannot return double for Null Value","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/NullableNumericAggregator.java","lineNumber":101,"sourceCode":"      throw new IllegalStateException(\"Cannot return float for Null Value\");\n    }\n    return delegate.getFloat();\n  }\n\n  @Override\n  public long getLong()\n  {\n    if (isNullResult) {\n      throw new IllegalStateException(\"Cannot return long for Null Value\");\n    }\n    return delegate.getLong();\n  }\n\n  @Override\n  public double getDouble()\n  {\n    if (isNullResult) {\n      throw new IllegalStateException(\"Cannot return double for Null Value\");\n    }\n    return delegate.getDouble();\n  }\n\n  @Override\n  public boolean isNull()\n  {\n    return isNullResult || delegate.isNull();\n  }\n\n  @Override\n  public void close()\n  {\n    delegate.close();\n  }\n}\n","sourceCodeStart":83,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/NullableNumericAggregator.java#L83-L118","documentation":"NullableNumericAggregator throws this IllegalStateException from getDouble() when the aggregated result is null (isNullResult == true). Druid models null numerics explicitly; returning NaN or 0.0 would be ambiguous, so callers must check isNull() first.","triggerScenarios":"Calling getDouble() on an aggregator whose underlying aggregation saw only null values during init/aggregate lifecycle.","commonSituations":"Double aggregations (doubleSum, doubleMin/Max, doubleFirst/Last, average) over all-null or missing columns; custom extraction code bypassing the null check; post-aggregator code reading raw aggregator state.","solutions":["Guard with agg.isNull() before calling getDouble()","Confirm the query targets the right column and segments actually contain non-null data","Check that the nullable wrapper is being used with a null-aware metric factory as intended","If results should never be null, coalesce the input (e.g., use a nullToDefault expression or filter nulls)"],"exampleFix":"// before\ndouble v = agg.getDouble();\n// after\ndouble v = agg.isNull() ? 0.0d /* or handle null */ : agg.getDouble();","handlingStrategy":"type-guard","validationCode":"if (agg.isNull()) {\n  return null;\n}","typeGuard":"Double value = agg.isNull() ? null : agg.getDouble();","tryCatchPattern":"try {\n  return agg.getDouble();\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Cannot return double for Null Value\")) {\n    return null;\n  }\n  throw e;\n}","preventionTips":["Use isNull() as the gate before getDouble()","Prefer boxed results or Optional in extraction layers to carry nullability","Coalesce nulls in the query itself (expressions/filters) when a numeric default is acceptable","Cover null-heavy data in aggregation unit tests"],"tags":["java","aggregation","null-handling"],"backgroundTag":"internal-invariant-violation","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"}