{"record":{"id":"f8537078a7f4bd9c","repo":"redis/jedis","slug":"at-least-one-aggregator-is-required","errorCode":null,"errorMessage":"At least one aggregator is required","messagePattern":"At least one aggregator is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/timeseries/TSRangeParams.java","lineNumber":135,"sourceCode":"    }\n\n    return this;\n  }\n\n  /**\n   * Specifies multiple aggregators to be applied in a single {@code TS.RANGE} / {@code TS.REVRANGE} call. Aggregators are\n   * sent on the wire in the given order and the response values appear in the same order in {@link TSElement#getValues()}.\n   * Single-element arrays are accepted and behave like {@link #aggregation(AggregationType, long)}.\n   *\n   * @param aggregators ordered, non-empty list of aggregators\n   * @param bucketDuration aggregation bucket duration in milliseconds\n   * @return this\n   * @throws IllegalArgumentException if {@code aggregators} is empty\n   */\n  public TSRangeParams aggregation(AggregationType[] aggregators, long bucketDuration) {\n    if (aggregators != null) {\n      if (aggregators.length == 0) {\n        throw new IllegalArgumentException(\"At least one aggregator is required\");\n      }\n      for (AggregationType a : aggregators) {\n        if (a == null) {\n          throw new IllegalArgumentException(\"Aggregators must not contain null elements\");\n        }\n      }\n      this.aggregators = aggregators;\n      this.bucketDuration = bucketDuration;\n    } else {\n      this.aggregators = null;\n      this.bucketDuration = 0;\n    }\n\n    return this;\n  }\n\n  /**\n   * This requires AGGREGATION.","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/timeseries/TSRangeParams.java#L117-L153","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nparams.aggregation(selectedAggs.toArray(new AggregationType[0]), 60000); // throws when empty\n// after\nif (selectedAggs.isEmpty()) {\n  params.aggregation(null, 0);\n} else {\n  params.aggregation(selectedAggs.toArray(new AggregationType[0]), 60000);\n}","handlingStrategy":"validation","validationCode":"if (aggs == null || aggs.length == 0) {\n  params.aggregation(null, 0);\n} else {\n  params.aggregation(aggs, bucketMs);\n}","typeGuard":"static boolean hasAggregators(AggregationType[] a) { return a != null && a.length > 0; }","tryCatchPattern":"try { params.aggregation(aggs, bucketMs); } catch (IllegalArgumentException e) { params.aggregation(null, 0); }","preventionTips":["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"],"tags":["java","validation","timeseries","illegal-argument"],"backgroundTag":"empty-required-field","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}