{"record":{"id":"b1b26904bf798e56","repo":"apache/druid","slug":"expected-1-child-got-d","errorCode":null,"errorMessage":"Expected [1] child, got [%d]","messagePattern":"Expected \\[1\\] child, got \\[(.+?)\\]","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/FilteredDataSource.java","lineNumber":96,"sourceCode":"  }\n\n  @Override\n  public Set<String> getTableNames()\n  {\n    return base.getTableNames();\n  }\n\n  @Override\n  public List<DataSource> getChildren()\n  {\n    return ImmutableList.of(base);\n  }\n\n  @Override\n  public DataSource withChildren(List<DataSource> children)\n  {\n    if (children.size() != 1) {\n      throw new IAE(\"Expected [1] child, got [%d]\", children.size());\n    }\n\n    return new FilteredDataSource(children.get(0), filter);\n  }\n\n  @Override\n  public boolean isCacheable(boolean isBroker)\n  {\n    return false;\n  }\n\n  @Override\n  public boolean isGlobal()\n  {\n    return base.isGlobal();\n  }\n\n  @Override","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/FilteredDataSource.java#L78-L114","documentation":"A FilteredDataSource wraps exactly one child data source plus a filter. DataSource.withChildren(children) replaces the child list, and this implementation requires exactly one child; any other count is rejected with this IllegalArgumentException to keep the data source tree structurally valid during query planning/rewriting.","triggerScenarios":"Calling filteredDataSource.withChildren(list) with an empty list or a list of 2+ data sources, typically from a planner/rewriter pass that miscounts children when rebuilding a datasource tree.","commonSituations":"Custom query tooling or extension code that recursively rebuilds data sources; bugs in datasource-rewriting utilities (e.g. analysis/replacement passes) that collect children from multiple sources into one list.","solutions":["Ensure the children list passed to withChildren contains exactly the single child of the FilteredDataSource.","When rewriting, preserve the original child count by calling withChildren on the correct DataSource node type rather than a sibling node.","Inspect the rewriting code that produced the list; it likely aggregated children of a parent (e.g. a join) and applied them to a filtered child."],"exampleFix":"// before\nds.withChildren(allChildren); // allChildren.size() == 3\n// after\nds.withChildren(allChildren.subList(0, 1)); // filtered datasource takes only its own child","handlingStrategy":"validation","validationCode":"if (children.size() != 1) {\n  throw new IllegalArgumentException(\"FilteredDataSource expects exactly 1 child, got \" + children.size());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track each datasource's own children during rewrites; never share a global children list.","Unit-test rewrite passes against trees containing FilteredDataSource.","Assert child counts before calling withChildren on any DataSource."],"tags":["query-planning","datasource","invalid-argument-value"],"backgroundTag":"missing-required-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"}