apache/druid · error · IllegalArgumentException
Expected [1] child, got [%d]
Error message
Expected [1] child, got [%d]
What it means
DataSource.withChildren is part of the DataSource transform protocol: RestrictedDataSource has exactly one child (the base TableDataSource), so callers must pass a single-element list. Any other size is a caller contract violation and Druid throws IAE immediately.
Source
Thrown at processing/src/main/java/org/apache/druid/query/RestrictedDataSource.java:102
}
@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 create(children.get(0), policy);
}
@Override
public boolean isCacheable(boolean isBroker)
{
return false;
}
@Override
public boolean isGlobal()
{
return base.isGlobal();
}
@OverrideView on GitHub (pinned to 9b90983fd2)
Solutions
- Pass exactly a one-element list containing the base datasource
- Check DataSource getChild()/children arity before building the children list in rewrite code
- If you intend zero children, do not wrap in RestrictedDataSource at all
Example fix
// before DataSource ds = restricted.withChildren(Collections.emptyList()); // after DataSource ds = restricted.withChildren(Collections.singletonList(base));
Defensive patterns
Strategy: validation
Validate before calling
if (ds instanceof RestrictedDataSource && children.size() != 1) {
throw new IllegalStateException("RestrictedDataSource requires exactly 1 child");
} Type guard
boolean isSingleChild(DataSource ds) {
return ds.getChildren().size() == 1;
} Try / catch
try {
DataSource rewritten = restricted.withChildren(children);
} catch (IllegalArgumentException e) {
// correct arity and retry
} Prevention
- Build children lists from ds.getChildren() so arity always matches
- Branch on datasource type in generic rewrite loops
When it happens
Trigger: Calling withChildren with an empty list, or with more than one data source, e.g. generic rewrite code that fans a datasource out to N children or passes an empty children list after removing a datasource.
Common situations: Query rewrite/planner code that recursively rebuilds datasource trees; tools calling withChildren on all datasources uniformly without accounting for arity; accidentally dropping the single child 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 [%d] children, got [%d]
- Expected [1] child, 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/0a4383038eda71a3.
Report an issue: GitHub.