redis/jedis · error · IllegalArgumentException

FILTER arguments must be set.

Error message

FILTER arguments must be set.

What it means

TSMRangeParams.addParams(CommandArguments) serializes the parameters into the TS.MRANGE/TS.MREVRANGE command. A multi-key time-series range query is meaningless without a FILTER clause, so if filters was never set (addFilter never called), it throws IllegalArgumentException("FILTER arguments must be set.") at command-build time rather than sending a broken command to Redis.

Solutions

  1. Call addFilter before executing, e.g. params.addFilter(QueryBuilders.equal("sensor", "temp")), or use the withFilters style API.
  2. If no filter is applicable, use the single-key TS.RANGE (TSRangeParams) API instead of MRANGE.
  3. Add a pre-execution check that filters were configured whenever MRANGE is used, with a clear error for the caller.

Example fix

// before
TSMRangeParams p = new TSMRangeParams(0, System.currentTimeMillis());
jedis.ts.mrange(p); // throws: no FILTER
// after
TSMRangeParams p = new TSMRangeParams(0, System.currentTimeMillis())
    .addFilter(new Filters().equals("sensor", "temp"));
jedis.ts.mrange(p);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(filters, "TS.MRANGE requires at least one FILTER; call addFilter before executing");
jedis.ts.mrange(params);

Type guard

boolean readyForMrange(TSMRangeParams p) {
  return p != null; // and ensure addFilter was called; track it in your builder wrapper
}

Try / catch

try {
  Map<String, TSMRangeResult> r = jedis.ts.mrange(params);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("FILTER")) {
    throw new IllegalStateException("Multi-key range queries need filters; use TSRangeParams for single-key queries");
  }
  throw e;
}

Prevention

When it happens

Trigger: Executing ts.mrange(params...) with a TSMRangeParams built without calling addFilter(...), e.g. new TSMRangeParams(from, to).aggregation(...) followed directly by the query call.

Common situations: Copy-pasting single-key TS.RANGE param construction (which needs no filter) for the multi-key MRANGE API; building params dynamically where the filter-adding branch is skipped because the filter list is empty; migration from TSMGET-style calls.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/timeseries/TSMRangeParams.java:247

    return this;
  }

  public TSMRangeParams filter(String... filters) {
    this.filters = filters;
    return this;
  }

  public TSMRangeParams groupBy(String label, String reduce) {
    this.groupByLabel = label;
    this.groupByReduce = reduce;
    return this;
  }

  @Override
  public void addParams(CommandArguments args) {

    if (filters == null) {
      throw new IllegalArgumentException("FILTER arguments must be set.");
    }

    if (excludeEmpty && groupByLabel != null && groupByReduce != null) {
      throw new IllegalArgumentException("EXCLUDEEMPTY is not allowed with GROUPBY.");
    }

    if (fromTimestamp == null) {
      args.add(MINUS);
    } else {
      args.add(toByteArray(fromTimestamp));
    }

    if (toTimestamp == null) {
      args.add(PLUS);
    } else {
      args.add(toByteArray(toTimestamp));
    }

View on GitHub (pinned to 6dac31d4c2)