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
- Call addFilter before executing, e.g. params.addFilter(QueryBuilders.equal("sensor", "temp")), or use the withFilters style API.
- If no filter is applicable, use the single-key TS.RANGE (TSRangeParams) API instead of MRANGE.
- 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
- Always pair TSMRangeParams with at least one addFilter call.
- Wrap multi-key query construction in a helper that enforces filter presence.
- Use TSRangeParams (single-key) when no filter is needed.
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
- Aggregators must be non-null and non-empty
- Aggregators must not contain null elements
- EXCLUDEEMPTY is not allowed with GROUPBY.
- Aggregators must be non-null and non-empty
- Aggregators must not contain null elements
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)