apache/druid · error · org.apache.druid.java.util.common.IAE

Cannot accept both 'splitPoints' and 'numBins'

Error message

Cannot accept both 'splitPoints' and 'numBins'

What it means

DoublesSketchToHistogramPostAggregator can size the histogram either from explicit splitPoints or from a numBins count, but not both. The constructor validates this and throws IllegalArgumentException when both parameters are supplied, since the two would define conflicting bin boundaries.

Source

Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregator.java:62

  private final String name;
  private final PostAggregator field;
  private final double[] splitPoints;
  private final Integer numBins;

  @JsonCreator
  public DoublesSketchToHistogramPostAggregator(
      @JsonProperty("name") final String name,
      @JsonProperty("field") final PostAggregator field,
      @JsonProperty("splitPoints") @Nullable final double[] splitPoints,
      @JsonProperty("numBins") @Nullable final Integer numBins)
  {
    this.name = Preconditions.checkNotNull(name, "name is null");
    this.field = Preconditions.checkNotNull(field, "field is null");
    this.splitPoints = splitPoints;
    this.numBins = numBins;
    if (splitPoints != null && numBins != null) {
      throw new IAE("Cannot accept both 'splitPoints' and 'numBins'");
    }
  }

  @Override
  public Object compute(final Map<String, Object> combinedAggregators)
  {
    final DoublesSketch sketch = (DoublesSketch) field.compute(combinedAggregators);
    final int numBins = this.splitPoints != null ? this.splitPoints.length + 1 :
        (this.numBins != null ? this.numBins.intValue() : DEFAULT_NUM_BINS);
    if (numBins < 2) {
      throw new IAE("at least 2 bins expected");
    }
    if (sketch.isEmpty()) {
      final double[] histogram = new double[numBins];
      Arrays.fill(histogram, Double.NaN);
      return histogram;
    }
    final double[] splitPoints;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove 'splitPoints' if you want evenly spaced bins computed from numBins.
  2. Remove 'numBins' if you want bins bounded by your explicit splitPoints.
  3. Null out one of the two fields in the code path that builds the spec dynamically.

Example fix

// before
{"type":"quantilesDoublesSketchToHistogram","field":{...},"splitPoints":[0.25,0.75],"numBins":10}
// after
{"type":"quantilesDoublesSketchToHistogram","field":{...},"splitPoints":[0.25,0.75]}
Defensive patterns

Strategy: validation

Validate before calling

if (spec.splitPoints != null && spec.numBins != null) { throw new IllegalArgumentException("Provide either splitPoints or numBins, not both"); }

Try / catch

try { new DoublesSketchToHistogramPostAggregator(name, field, splitPoints, numBins); } catch (IllegalArgumentException e) { /* drop numBins or splitPoints and retry */ }

Prevention

When it happens

Trigger: Constructing the post-aggregator (in JSON or Java) with both a 'splitPoints' array and a 'numBins' value set to non-null at the same time.

Common situations: Copy-pasting a spec and adding numBins while leaving splitPoints in place; programmatic spec building where both optional fields are populated from configuration.

Related errors


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