apache/druid · error · IllegalArgumentException

Illegal number of fields[%d], must be > 1

Error message

Illegal number of fields[%d], must be > 1

What it means

ArrayOfDoublesSketchSetOpPostAggregator's constructor validates that the set operation (UNION, INTERSECT, NOT) has more than one input field, since set operations are defined between multiple sketches. A field list of size <= 1 triggers IAE.

Source

Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/tuple/ArrayOfDoublesSketchSetOpPostAggregator.java:67

  private final int numberOfValues;

  @JsonCreator
  public ArrayOfDoublesSketchSetOpPostAggregator(
      @JsonProperty("name") final String name,
      @JsonProperty("operation") final String operation,
      @JsonProperty("nominalEntries") @Nullable final Integer nominalEntries,
      @JsonProperty("numberOfValues") @Nullable final Integer numberOfValues,
      @JsonProperty("fields") List<PostAggregator> fields
  )
  {
    super(name, fields);
    this.operation = ArrayOfDoublesSketchOperations.Operation.valueOf(operation);
    this.nominalEntries = nominalEntries == null ? ThetaUtil.DEFAULT_NOMINAL_ENTRIES : nominalEntries;
    this.numberOfValues = numberOfValues == null ? 1 : numberOfValues;
    Util.checkIfIntPowerOf2(this.nominalEntries, "size");

    if (fields.size() <= 1) {
      throw new IAE("Illegal number of fields[%d], must be > 1", fields.size());
    }
  }

  @Override
  public Comparator<ArrayOfDoublesSketch> getComparator()
  {
    return ArrayOfDoublesSketchAggregatorFactory.COMPARATOR;
  }

  @Override
  public ArrayOfDoublesSketch compute(final Map<String, Object> combinedAggregators)
  {
    final ArrayOfDoublesSketch[] sketches = new ArrayOfDoublesSketch[getFields().size()];
    for (int i = 0; i < sketches.length; i++) {
      sketches[i] = (ArrayOfDoublesSketch) getFields().get(i).compute(combinedAggregators);
    }
    return operation.apply(nominalEntries, numberOfValues, sketches);
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Provide at least two fields in the post-aggregator's fields array
  2. For a single-input NOT operation, use a different construction path or wrap the single sketch appropriately
  3. Validate the JSON query's postAggregator spec before submission

Example fix

// before
new ArrayOfDoublesSketchSetOpPostAggregator("set_op", "INTERSECT", List.of(fieldA), 16384, 1);
// after
new ArrayOfDoublesSketchSetOpPostAggregator("set_op", "INTERSECT", List.of(fieldA, fieldB), 16384, 1);
Defensive patterns

Strategy: validation

Validate before calling

if (fields == null || fields.size() <= 1) {
  throw new IllegalArgumentException("Set op post-aggregator requires > 1 field, got "
      + (fields == null ? 0 : fields.size()));
}

Type guard

boolean hasEnoughFields = fields != null && fields.size() > 1;

Try / catch

try {
  new ArrayOfDoublesSketchSetOpPostAggregator(name, operation, fields, nominalEntries, numValues);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Illegal number of fields")) {
    // fix the query spec / add more fields
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Constructing the post-aggregator (programmatically or via JSON query parsing) with fields omitted, empty, or containing exactly one entry.

Common situations: Hand-written native JSON queries with a typo in the fields key; programmatic query builders adding a single field; a NOT operation mistakenly given only one field even though NOT allows one at runtime (constructor still demands >1).

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/1080259cdbf3b9dd. Report an issue: GitHub.