{"record":{"id":"31c4ceee2a380a6b","repo":"apache/druid","slug":"got-a-null-list-of-results","errorCode":null,"errorMessage":"Got a null list of results","messagePattern":"Got a null list of results","errorType":"exception","errorClass":"ISE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java","lineNumber":120,"sourceCode":"                          }\n\n                          final AbstractPrioritizedQueryRunnerCallable<Iterable<T>, T> callable = new AbstractPrioritizedQueryRunnerCallable<>(\n                              priority,\n                              input\n                          )\n                          {\n                            @Override\n                            public Iterable<T> call()\n                            {\n                              try {\n                                Sequence<T> result = input.run(threadSafeQueryPlus, responseContext);\n                                if (result == null) {\n                                  throw new ISE(\"Got a null result! Segments are missing!\");\n                                }\n\n                                List<T> retVal = result.toList();\n                                if (retVal == null) {\n                                  throw new ISE(\"Got a null list of results\");\n                                }\n\n                                return retVal;\n                              }\n                              catch (QueryInterruptedException e) {\n                                throw new RuntimeException(e);\n                              }\n                              catch (QueryTimeoutException e) {\n                                throw e;\n                              }\n                              catch (Exception e) {\n                                if (query.context().isDebug()) {\n                                  log.error(e, \"Exception with one of the sequences!\");\n                                } else {\n                                  log.noStackTrace().error(e, \"Exception with one of the sequences!\");\n                                }\n                                Throwables.throwIfUnchecked(e);\n                                throw new RuntimeException(e);","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java#L102-L138","documentation":"Defensive check immediately after result.toList() in ChainedExecutionQueryRunner.call(): even if the Sequence is non-null, its toList() materialization returned null, which the query engine treats as an impossible state. This guards against Sequence implementations that return null instead of an empty list.","triggerScenarios":"A Sequence implementation whose toList() returns null instead of Sequences.toList contract of an empty list; custom Sequence wrappers or extension code materializing results incorrectly; corrupt result adapters inserted between segment runner and the chain.","commonSituations":"Custom QueryRunner/Sequence implementations from extensions or tests; newer Druid API changes where Sequence.toList semantics differ from a hand-rolled adapter; memory-pressure paths that silently null out buffers in non-standard forks.","solutions":["Fix the Sequence/QueryRunner implementation to return an empty List instead of null from toList()","Use Sequences.toList(...) or wrap with Sequences.simple(...) so the standard materialization path is used","Search the extension classpath for custom Sequence classes and validate them with a unit test materializing an empty result","Upgrade extensions to match the Druid core version in use"],"exampleFix":"// before\nList<T> toList() {\n  return null; // nothing collected\n}\n// after\nList<T> toList() {\n  return collected == null ? Collections.emptyList() : collected;\n}","handlingStrategy":"type-guard","validationCode":"// unit-test custom Sequence adapters: materialize an empty result\nList<Object> out = Sequences.toList(myAdapter.run(q, ctx), ( Accumulator ) null);","typeGuard":"boolean isValidToList(Sequence<?> seq) {\n  if (seq == null) return false;\n  List<?> l = seq.toList();\n  return l != null;\n}","tryCatchPattern":"try {\n  List<T> rows = runQuery();\n} catch (IllegalStateException e) {\n  if (\"Got a null list of results\".equals(e.getMessage())) {\n    // fix/replace the Sequence adapter returning null\n  }\n}","preventionTips":["Never return null from Sequence.toList(); return Collections.emptyList()","Use core Sequences helpers instead of custom materialization","Test extensions against an empty datasource to catch null-returning adapters"],"tags":["druid","query-execution","null-result","sequence"],"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-14T11:17:12.474Z"}