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

  1. Pass at least one aggregator, e.g. aggregation(new AggregationType[]{AggregationType.AVG}, 60000).
  2. Use aggregation(null, 0) (or the null path) when aggregation should be disabled — do not pass an empty array.
  3. 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

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


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)