{"record":{"id":"07f79a9a762ea5c9","repo":"apache/druid","slug":"cannot-have-a-null-result","errorCode":null,"errorMessage":"Cannot have a null result!","messagePattern":"Cannot have a null result!","errorType":"exception","errorClass":"ISE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/FinalizeResultsQueryRunner.java","lineNumber":92,"sourceCode":"      metricManipulationFn = MetricManipulatorFns.identity();\n    }\n\n    if (isBySegment) {\n      finalizerFn = new Function<T, Result<BySegmentResultValue<T>>>()\n      {\n        final Function<T, T> baseFinalizer = toolChest.makePostComputeManipulatorFn(\n            query,\n            metricManipulationFn\n        );\n\n        @Override\n        public Result<BySegmentResultValue<T>> apply(T input)\n        {\n          //noinspection unchecked (input is not actually a T; see class-level javadoc)\n          Result<BySegmentResultValueClass<T>> result = (Result<BySegmentResultValueClass<T>>) input;\n\n          if (input == null) {\n            throw new ISE(\"Cannot have a null result!\");\n          }\n\n          BySegmentResultValue<T> resultsClass = result.getValue();\n\n          final List<T> originalResults = resultsClass.getResults();\n          final ArrayList<T> transformedResults = new ArrayList<>(originalResults.size());\n          for (T originalResult : originalResults) {\n            transformedResults.add(baseFinalizer.apply(originalResult));\n          }\n\n          return new Result<>(\n              result.getTimestamp(),\n              new BySegmentResultValueClass<>(\n                  transformedResults,\n                  resultsClass.getSegmentId(),\n                  resultsClass.getInterval()\n              )\n          );","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/FinalizeResultsQueryRunner.java#L74-L110","documentation":"FinalizeResultsQueryRunner post-processes query results, and for by-segment results it casts each input to a Result<BySegmentResultValueClass<T>>. The null check (an internal invariant) throws IllegalStateException when a null result reaches the finalize function — the value arrived as null even though the cast line executes first, so this check exists to fail loudly on a null that violates the runner's contract.","triggerScenarios":"A query tool/wrapper or custom QueryRunner upstream yields a null Result into the finalize chain when merging by-segment results (e.g. during caching or concatenation merges).","commonSituations":"Custom QueryRunner implementations or extensions that return null instead of an empty/absent result; query lifecycle bugs where a segment result was dropped but the pipeline still expected a Result object.","solutions":["Find the upstream QueryRunner returning null results and make it return an empty Result or skip emission instead.","Wrap custom runners so null results are filtered out before the finalize stage.","Verify caching/merge configuration (by-segment query caching) isn't producing null entries in the results list."],"exampleFix":"// before\nreturn results.isEmpty() ? null : new Result<>(...); // null leaks to finalize\n// after\nreturn new Result<>(timestamp, new BySegmentResultValueClass<>(results, segmentId, interval)); // always non-null","handlingStrategy":"try-catch","validationCode":"if (input == null) {\n  // skip or substitute an empty result before feeding the finalize chain\n}","typeGuard":null,"tryCatchPattern":"try {\n  Result<BySegmentResultValueClass<T>> r = finalize(input);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Cannot have a null result\")) {\n    // log and skip this result\n  } else { throw e; }\n}","preventionTips":["Never return null Results from custom QueryRunners.","Filter nulls out of merged result sequences before finalize.","Test custom runners under by-segment caching."],"tags":["query-execution","null-pointer","internal-invariant-violation"],"backgroundTag":"null-argument","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"}