redis/jedis · error · IllegalArgumentException
Aggregators must not contain null elements
Error message
Aggregators must not contain null elements
What it means
TSRangeParams.aggregation(AggregationType[] aggregators, long bucketDuration) rejects null elements inside the aggregator array. A null AggregationType cannot be encoded into the AGGREGATION argument of TS.RANGE, so the library throws IllegalArgumentException during parameter building.
Solutions
- Replace null entries with valid AggregationType constants (MIN, MAX, AVG, SUM, COUNT, etc.).
- Fail at parse time when a configured aggregation name cannot be resolved to an AggregationType, instead of storing null.
- Filter with Objects::nonNull only if trailing nulls are semantically unwanted — but prefer fixing the producer so no nulls are created.
Example fix
// before
AggregationType[] aggs = new AggregationType[2];
aggs[0] = AggregationType.SUM;
params.aggregation(aggs, 10000); // aggs[1] == null -> throws
// after
AggregationType[] aggs = new AggregationType[]{AggregationType.SUM, AggregationType.AVG};
params.aggregation(aggs, 10000); Defensive patterns
Strategy: validation
Validate before calling
if (Arrays.stream(aggs).anyMatch(Objects::isNull)) {
throw new IllegalStateException("null aggregator in config");
}
params.aggregation(aggs, bucketMs); Type guard
static AggregationType[] nonNullAggs(AggregationType[] in) { return Arrays.stream(in).filter(Objects::nonNull).toArray(AggregationType[]::new); } Try / catch
try { params.aggregation(aggs, bucketMs); } catch (IllegalArgumentException e) { throw new ConfigurationException("null aggregator", e); } Prevention
- Fail at config parse time on unknown aggregation names
- Initialize arrays with all values, or use List.of(...)
- Run a null-scan on builder inputs in tests
When it happens
Trigger: Calling TSRangeParams.aggregation(new AggregationType[]{AggregationType.MIN, null}, bucketDuration), or arrays produced by AggregationType[n] pre-sizing with unfilled slots.
Common situations: Mapping user-supplied aggregation names via a lookup that returns null for unknown values; deserialized configuration containing incomplete aggregator lists.
Related errors
- Aggregators must not contain null elements
- Aggregators must not contain null elements
- DriverInfo must not be null
- Aggregators must be non-null and non-empty
- FILTER arguments must be set.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/482845f1024cba59.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/timeseries/TSRangeParams.java:139
/**
* 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.
*/
public TSRangeParams bucketTimestamp(String bucketTimestamp) {
this.bucketTimestamp = encode(bucketTimestamp);
return this;View on GitHub (pinned to 6dac31d4c2)