redis/jedis · error · IllegalArgumentException
Aggregators must be non-null and non-empty
Error message
Aggregators must be non-null and non-empty
What it means
TSMRangeParams.aggregation(AggregationType[] aggregators, long bucketDuration) validates that when a non-null aggregators array is supplied it is non-empty and contains no null elements, since TS.RANGE/TS.MSEARCH aggregation requires at least one concrete aggregator. An empty array throws IllegalArgumentException("Aggregators must be non-null and non-empty").
Solutions
- Pass at least one AggregationType, e.g. aggregation(new AggregationType[]{AggregationType.AVG}, 60000).
- Guard the call site: if the aggregator list is empty, skip setting aggregation instead of passing an empty array.
- Validate user/config input to ensure at least one aggregation is selected when aggregation is intended.
Example fix
// before
params.aggregation(aggList.toArray(new AggregationType[0]), 60000); // throws when empty
// after
if (!aggList.isEmpty()) {
params.aggregation(aggList.toArray(new AggregationType[0]), 60000);
} Defensive patterns
Strategy: validation
Validate before calling
if (aggregators != null && aggregators.length == 0) {
throw new IllegalArgumentException("Provide at least one AggregationType");
}
params.aggregation(aggregators, bucketDuration); Type guard
boolean hasAggregators(AggregationType[] a) {
return a != null && a.length > 0;
} Try / catch
try {
params.aggregation(aggs, bucketMs);
} catch (IllegalArgumentException e) {
params = new TSMRangeParams(from, to); // proceed without aggregation
log.warn("Aggregation skipped: {}", e.getMessage());
} Prevention
- Only call aggregation(...) when at least one aggregator was selected.
- Convert collections with toArray(new AggregationType[0]) and check isEmpty first.
- Make aggregation an optional feature: empty selection means no aggregation clause, not an empty array.
When it happens
Trigger: Calling aggregation(new AggregationType[0], bucketDuration) or passing an empty array produced from an empty list/collection (e.g. aggregation(aggregatorList.toArray(new AggregationType[0]), 60000) with an empty list).
Common situations: Building range queries from user-selected aggregations where none were selected; config-driven dashboards where the aggregation list defaults to empty; refactors replacing the single AggregationType overload with the array overload but passing an empty array.
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 not contain null elements
- FILTER arguments must be set.
- EXCLUDEEMPTY is not allowed with GROUPBY.
- Aggregators must be non-null and non-empty
- Aggregators must not contain null elements
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/e98b762ce14c8b52.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/timeseries/TSMRangeParams.java:158
this.bucketDuration = 0;
}
return this;
}
/**
* Specifies multiple aggregators to be applied in a single {@code TS.MRANGE} / {@code TS.MREVRANGE} 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 TSMRangeParams aggregation(AggregationType[] aggregators, long bucketDuration) {
if (aggregators != null) {
if (aggregators.length == 0) {
throw new IllegalArgumentException("Aggregators must be non-null and non-empty");
}
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)