apache/druid · error · IllegalArgumentException

Illegal number of fields

Error message

Illegal number of fields[%d], must be 2

What it means

The ArrayOfDoublesSketchTTestPostAggregator performs a two-sample Student's t-test, which by definition requires exactly two sketch inputs. The constructor validates the 'fields' list at query-spec parse time and throws this IllegalArgumentException when the count is anything other than 2, failing fast before query execution.

Solutions

  1. Ensure the post-aggregator 'fields' list contains exactly two ArrayOfDoublesSketch aggregator references
  2. If comparing more than two sketches, run separate tTest post-aggregators for each pair instead of one with N fields
  3. Validate the count of postAggregator.fields in client code before deserializing/submitting the query

Example fix

// before
"postAggregators": [{ "type": "tTest", "fields": ["sketchA"] }]
// after
"postAggregators": [{ "type": "tTest", "fields": ["sketchA", "sketchB"] }]
Defensive patterns

Strategy: validation

Validate before calling

List<PostAggregator> fields = postAggregatorSpec.get("fields");
if (fields == null || fields.size() != 2) {
  throw new IllegalArgumentException("tTest post-aggregator requires exactly 2 fields, got: " + (fields == null ? 0 : fields.size()));
}

Try / catch

try {
  queryClient.run(query);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("Illegal number of fields")) {
    throw new QuerySpecException("tTest post-aggregator must have exactly 2 sketch fields", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Submitting a native query or SQL query whose JSON post-aggregator spec for 'tTest' supplies fewer than 2 fields (e.g. only one sketch aggregator reference) or more than 2 fields (e.g. three sketch references).

Common situations: Hand-written query JSON missing one field; programmatic query builders appending fields in a loop; copying a t-test spec from an ANOVA-style example with multiple sketches; users assuming t-test generalizes to >2 samples.

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/8b93fc3c9025254e. Report an issue: GitHub.

Appendix: source

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

import java.util.Map;

/**
 * Performs Student's t-test and returns a list of p-values given two instances of {@link ArrayOfDoublesSketch}.
 * The result will be N double values, where N is the number of double values kept in the sketch per key.
 * See <a href=http://commons.apache.org/proper/commons-math/javadocs/api-3.4/org/apache/commons/math3/stat/inference/TTest.html>Student's t-test</a>
 */
public class ArrayOfDoublesSketchTTestPostAggregator extends ArrayOfDoublesSketchMultiPostAggregator
{

  @JsonCreator
  public ArrayOfDoublesSketchTTestPostAggregator(
      @JsonProperty("name") final String name,
      @JsonProperty("fields") List<PostAggregator> fields
  )
  {
    super(name, fields);
    if (fields.size() != 2) {
      throw new IAE("Illegal number of fields[%d], must be 2", fields.size());
    }
  }

  @Override
  public Comparator<double[]> getComparator()
  {
    throw new IAE("Comparing arrays of p values is not supported");
  }

  @Override
  public double[] compute(final Map<String, Object> combinedAggregators)
  {
    final ArrayOfDoublesSketch sketch1 = (ArrayOfDoublesSketch) getFields().get(0).compute(combinedAggregators);
    final ArrayOfDoublesSketch sketch2 = (ArrayOfDoublesSketch) getFields().get(1).compute(combinedAggregators);
    if (sketch1.getNumValues() != sketch2.getNumValues()) {
      throw new IAE(
          "Sketches have different number of values: %d and %d",
          sketch1.getNumValues(),

View on GitHub (pinned to 9b90983fd2)