redis/jedis · error · IllegalArgumentException
At least one aggregator is required
Error message
At least one aggregator is required
What it means
TSRangeParams.aggregation(AggregationType[] aggregators, long bucketDuration) allows null to disable aggregation but rejects an empty array, since the AGGREGATION clause for TS.RANGE needs at least one aggregator. The library throws IllegalArgumentException up front so the malformed query never reaches Redis.
Solutions
- Pass at least one aggregator, e.g. aggregation(new AggregationType[]{AggregationType.AVG}, 60000).
- Use aggregation(null, 0) (or the null path) when aggregation should be disabled — do not pass an empty array.
- Check the source collection with isEmpty() before converting to an array and branch to the null case.
Example fix
// before
params.aggregation(selectedAggs.toArray(new AggregationType[0]), 60000); // throws when empty
// after
if (selectedAggs.isEmpty()) {
params.aggregation(null, 0);
} else {
params.aggregation(selectedAggs.toArray(new AggregationType[0]), 60000);
} Defensive patterns
Strategy: validation
Validate before calling
if (aggs == null || aggs.length == 0) {
params.aggregation(null, 0);
} else {
params.aggregation(aggs, bucketMs);
} Type guard
static boolean hasAggregators(AggregationType[] a) { return a != null && a.length > 0; } Try / catch
try { params.aggregation(aggs, bucketMs); } catch (IllegalArgumentException e) { params.aggregation(null, 0); } Prevention
- Empty means invalid, null means disabled — encode that in helper wrappers
- Guard toArray() conversions of possibly-empty collections
- Prefer the single-enum aggregation(AggregationType, long) overload when there is exactly one aggregator
When it happens
Trigger: Calling TSRangeParams.aggregation(new AggregationType[0], bucketDuration) — commonly from an empty list converted with toArray(), or code that filters aggregators and drops all of them.
Common situations: Dashboard-style queries where aggregation options come from user config and an empty selection falls through to the aggregation(...) call; migration from deprecated aggregation(AggregationType, long) single-arg overloads to the array overload.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Aggregators must be non-null and non-empty
- Aggregators must not contain null elements
- FILTER arguments must be set.
- EXCLUDEEMPTY is not allowed with GROUPBY.
- Aggregators must be non-null and non-empty
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/f8537078a7f4bd9c.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/timeseries/TSRangeParams.java:135
}
return this;
}
/**
* Specifies multiple aggregators to be applied in a single {@code TS.RANGE} / {@code TS.REVRANGE} call. Aggregators are
* sent on the wire in the given order and the response values appear in the same order in {@link TSElement#getValues()}.
* Single-element arrays are accepted and behave like {@link #aggregation(AggregationType, long)}.
*
* @param aggregators ordered, non-empty list of aggregators
* @param bucketDuration aggregation bucket duration in milliseconds
* @return this
* @throws IllegalArgumentException if {@code aggregators} is empty
*/
public TSRangeParams aggregation(AggregationType[] aggregators, long bucketDuration) {
if (aggregators != null) {
if (aggregators.length == 0) {
throw new IllegalArgumentException("At least one aggregator is required");
}
for (AggregationType a : aggregators) {
if (a == null) {
throw new IllegalArgumentException("Aggregators must not contain null elements");
}
}
this.aggregators = aggregators;
this.bucketDuration = bucketDuration;
} else {
this.aggregators = null;
this.bucketDuration = 0;
}
return this;
}
/**
* This requires AGGREGATION.View on GitHub (pinned to 6dac31d4c2)