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
- Ensure the post-aggregator 'fields' list contains exactly two ArrayOfDoublesSketch aggregator references
- If comparing more than two sketches, run separate tTest post-aggregators for each pair instead of one with N fields
- 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
- Always declare exactly two ArrayOfDoublesSketch aggregators before referencing them in a tTest post-aggregator
- Validate post-aggregator field counts in query-builder helpers before serialization
- Never loop N sketches into one tTest; create pairwise tTest post-aggregators instead
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
- A-Not-B requires at least 1 sketch
- AggregatorFactoryNotMergeableException(this, other)
- AggregatorFactoryNotMergeableException(this, other)
- at least 2 bins expected
- at least 2 bins expected
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)