apache/druid · error · IllegalStateException
Ambiguous build, limit
Error message
Ambiguous build, limit[%s] or columnSpecs[%s] already set.
What it means
Inverse of the explicit-limitSpec check: ensureFluentLimitsNotSet throws ISE when fluent limit APIs (setLimit/addOrderByColumnSpec) were already used and an explicit limitSpec is then set on the same Builder, because the resulting limit configuration would be ambiguous.
Solutions
- Remove one of the two limit definitions — keep either the fluent limit or the explicit limitSpec
- Reset/rebuild the builder if limits from a previous stage should be discarded
- Check builder state (limit != Integer.MAX_VALUE or non-empty orderByColumnSpecs) before calling setLimitSpec
Example fix
// before
builder.setLimit(10).addOrderByColumnSpec(new OrderByColumnSpec("dim", ASC)).setLimitSpec(spec);
// after
builder.setLimitSpec(spec); // drop the fluent limit calls Defensive patterns
Strategy: validation
Validate before calling
if (limit != Integer.MAX_VALUE || !orderByColumnSpecs.isEmpty()) { /* fluent limits set — do not call setLimitSpec */ } Type guard
null
Try / catch
try { builder.setLimitSpec(spec); } catch (IllegalStateException e) { if (e.getMessage().contains("columnSpecs")) { /* clear fluent limits first */ } throw e; } Prevention
- Set the limitSpec before any fluent limit calls, or not at all
- Track builder limit state explicitly in wrapper classes
When it happens
Trigger: Calling Builder.setLimit(...) or addOrderByColumnSpec(...) and then setLimitSpec(...) on the same builder instance.
Common situations: Programmatic query building that first applies default sorting then a caller-supplied limitSpec; framework code layering limitSpec onto pre-configured builders; deserialization edge cases.
Related errors
- Ambiguous build, limitSpec
- buffer for list is too small, was
- Cannot force limit push down when a having spec is present.
- Duplicate output name
- Group key should be a single dimension
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6466dea928044cb5.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java:1132
{
Preconditions.checkNotNull(limitSpec);
ensureFluentLimitsNotSet();
this.limitSpec = limitSpec;
this.postProcessingFn = null;
return this;
}
private void ensureExplicitLimitSpecNotSet()
{
if (limitSpec != null) {
throw new ISE("Ambiguous build, limitSpec[%s] already set", limitSpec);
}
}
private void ensureFluentLimitsNotSet()
{
if (!(limit == Integer.MAX_VALUE && orderByColumnSpecs.isEmpty())) {
throw new ISE("Ambiguous build, limit[%s] or columnSpecs[%s] already set.", limit, orderByColumnSpecs);
}
}
public Builder setQuerySegmentSpec(QuerySegmentSpec querySegmentSpec)
{
this.querySegmentSpec = querySegmentSpec;
return this;
}
public Builder setDimFilter(@Nullable DimFilter dimFilter)
{
this.dimFilter = dimFilter;
return this;
}
public Builder setGranularity(Granularity granularity)
{
this.granularity = granularity;View on GitHub (pinned to 9b90983fd2)