redis/jedis · error · IllegalStateException

REDUCE COLLECT requires either fields(...) or fieldsAll()…

Error message

REDUCE COLLECT requires either fields(...) or fieldsAll() to be configured

What it means

When the CollectReducer serializes itself into command arguments (getOwnArgs), it requires a fields configuration: either explicit fields(...) or fieldsAll(). A REDUCE COLLECT with neither would produce a meaningless/unserverable FIELDS clause, so it throws this IllegalStateException at query build time.

Solutions

  1. Call fields("@field1", ...) or fieldsAll() on every CollectReducer before executing the query
  2. Guard dynamic builders: if the field list is empty, either use fieldsAll() or skip adding the COLLECT reducer
  3. Validate the aggregation builder in application code before sending (ensure each COLLECT reducer has fields set)

Example fix

// before
aggregationBuilder.reduce(new CollectReducer()); // IllegalStateException at build/send
// after
aggregationBuilder.reduce(new CollectReducer().fieldsAll());
// or
aggregationBuilder.reduce(new CollectReducer().fields("@title", "@tags"));
Defensive patterns

Strategy: validation

Validate before calling

// before sending the aggregation, verify every COLLECT reducer has fields
if (!allFields && (fields == null || fields.isEmpty())) {
  throw new IllegalStateException("CollectReducer needs fields(...) or fieldsAll()");
}

Type guard

null

Try / catch

try {
  AggregationResult r = client.ftAggregate(indexName, aggregationBuilder);
} catch (JedisException | IllegalStateException e) {
  // reducer misconfiguration — fix builder before retry
}

Prevention

When it happens

Trigger: Adding a bare new CollectReducer() to an AggregationBuilder's reduce() without ever calling fields(...) or fieldsAll(), then executing the aggregation.

Common situations: Skeleton reducer left unconfigured during development; dynamic builders that skip field configuration when a list is empty; copy-pasted reducer code where the fields call was deleted.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/e659587f8037c2af. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/search/aggr/CollectReducer.java:140

  /** Bound the output per group to the first {@code count} entries (offset 0). */
  public CollectReducer limit(int count) {
    return limit(0, count);
  }

  /** Bound the output per group to {@code count} entries starting at {@code offset}. */
  public CollectReducer limit(int offset, int count) {
    if (offset < 0 || count < 0) {
      throw new IllegalArgumentException("LIMIT offset and count must be non-negative");
    }
    this.limitOffset = offset;
    this.limitCount = count;
    return this;
  }

  @Override
  protected List<Object> getOwnArgs() {
    if (!allFields && fields.isEmpty()) {
      throw new IllegalStateException(
          "REDUCE COLLECT requires either fields(...) or fieldsAll() to be configured");
    }

    List<Object> args = new ArrayList<>();
    args.add(SearchKeyword.FIELDS);
    if (allFields) {
      args.add(Protocol.BYTES_ASTERISK);
    } else {
      args.add(fields.size());
      args.addAll(fields);
    }

    if (!sortFields.isEmpty()) {
      args.add(SearchKeyword.SORTBY);
      args.add(sortFields.size() << 1); // 2 tokens per @field/ASC|DESC pair
      for (SortedField sf : sortFields) {
        args.add(sf.getField());
        args.add(sf.getOrder());

View on GitHub (pinned to 6dac31d4c2)