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();
  }

  @Override

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Pass exactly Collections.singletonList(rewrittenChild)
  2. In generic rewrite code, branch on datasource type/arity before calling withChildren
  3. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1dd55317a07f588b. Report an issue: GitHub.