apache/druid · error · IllegalArgumentException
Expected [1] child, got [%d]
Error message
Expected [1] child, got [%d]
What it means
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.
Source
Thrown at processing/src/main/java/org/apache/druid/query/UnnestDataSource.java:108
}
@Override
public Set<String> getTableNames()
{
return base.getTableNames();
}
@Override
public List<DataSource> getChildren()
{
return ImmutableList.of(base);
}
@Override
public DataSource withChildren(List<DataSource> children)
{
if (children.size() != 1) {
throw new IAE("Expected [1] child, got [%d]", children.size());
}
return new UnnestDataSource(children.get(0), virtualColumn, unnestFilter);
}
@Override
public boolean isCacheable(boolean isBroker)
{
return false;
}
@Override
public boolean isGlobal()
{
return base.isGlobal();
}
@OverrideView on GitHub (pinned to 9b90983fd2)
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
Example fix
// before
DataSource rewritten = unnestDs.withChildren(allRewritten);
// after
DataSource rewritten = unnestDs.withChildren(
Collections.singletonList(rewrite(unnestDs.getChildren().get(0)))); Defensive patterns
Strategy: validation
Validate before calling
if (!(ds instanceof UnnestDataSource) || children.size() != 1) {
throw new IllegalStateException("UnnestDataSource requires exactly 1 child");
} Type guard
boolean isSingleChildUnnest(DataSource ds, List<DataSource> children) {
return ds instanceof UnnestDataSource && children.size() == 1;
} Try / catch
try {
DataSource rewritten = unnestDs.withChildren(children);
} catch (IllegalArgumentException e) {
// rebuild with singletonList(rewrite(originalChild))
} Prevention
- Map children from ds.getChildren() instead of a global list
- Branch on datasource type before generic withChildren calls
When it happens
Trigger: 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.
Common situations: Planner/rewrite passes that replace children of all datasources uniformly; code written for UnionDataSource (multi-child) reused on UnnestDataSource; emptying children list during transformation.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected [1] child, got [%d]
- Expected [%d] children, got [%d]
- Cannot handle dataSource [%s]
- Must have exactly one child
- Expected a TableDataSource, got data source type [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1dd55317a07f588b.
Report an issue: GitHub.