{"record":{"id":"1dd55317a07f588b","repo":"apache/druid","slug":"expected-1-child-got-d-1dd553","errorCode":null,"errorMessage":"Expected [1] child, got [%d]","messagePattern":"Expected \\[1\\] child, got \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/UnnestDataSource.java","lineNumber":108,"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 UnnestDataSource(children.get(0), virtualColumn, unnestFilter);\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":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/UnnestDataSource.java#L90-L126","documentation":"UnnestDataSource has exactly one child (the input datasource being unnested), so withChildren requires a single-element list. Any other count is a caller bug and Druid throws IAE. The returned UnnestDataSource keeps the same virtual columns and unnest filter with the new base datasource.","triggerScenarios":"Calling withChildren with an empty list or multiple children — typically generic rewrite code iterating query datasources, or passing children collected from the whole query rather than this datasource.","commonSituations":"Planner/rewrite passes that replace children of all datasources uniformly; code written for UnionDataSource (multi-child) reused on UnnestDataSource; emptying children list during transformation.","solutions":["Pass exactly Collections.singletonList(rewrittenChild)","In generic rewrite code, branch on datasource type/arity before calling withChildren","Inspect getChildren() to confirm the datasource is single-child"],"exampleFix":"// before\nDataSource rewritten = unnestDs.withChildren(allRewritten);\n// after\nDataSource rewritten = unnestDs.withChildren(\n    Collections.singletonList(rewrite(unnestDs.getChildren().get(0))));","handlingStrategy":"validation","validationCode":"if (!(ds instanceof UnnestDataSource) || children.size() != 1) {\n  throw new IllegalStateException(\"UnnestDataSource requires exactly 1 child\");\n}","typeGuard":"boolean isSingleChildUnnest(DataSource ds, List<DataSource> children) {\n  return ds instanceof UnnestDataSource && children.size() == 1;\n}","tryCatchPattern":"try {\n  DataSource rewritten = unnestDs.withChildren(children);\n} catch (IllegalArgumentException e) {\n  // rebuild with singletonList(rewrite(originalChild))\n}","preventionTips":["Map children from ds.getChildren() instead of a global list","Branch on datasource type before generic withChildren calls"],"tags":["druid","datasource","arity-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}