redis/jedis · error · IllegalArgumentException
LIMIT offset and count must be non-negative
Error message
LIMIT offset and count must be non-negative
What it means
CollectReducer.limit(offset, count) implements the aggregation LIMIT clause, which only accepts non-negative offset and count values. Passing either negative throws this IllegalArgumentException before any query is sent, preventing an invalid query from reaching the server.
Solutions
- Validate/clamp offset and count to >= 0 before calling limit
- For 'no limit' behavior, omit the limit() call instead of passing -1
- Fix pagination arithmetic: use offset = page * size with page starting at 0, or Math.max(0, computed)
Example fix
// before reducer.limit(page - 1, pageSize); // IllegalArgumentException when page==0 // after reducer.limit(Math.max(0, (page - 1)) * pageSize, Math.max(0, pageSize));
Defensive patterns
Strategy: validation
Validate before calling
if (offset < 0 || count < 0) {
throw new IllegalArgumentException("limit offset/count must be >= 0");
}
reducer.limit(offset, count); Type guard
null
Try / catch
try {
reducer.limit(offset, count);
} catch (IllegalArgumentException e) {
// clamp or correct pagination math before retrying
} Prevention
- Clamp user-supplied paging values with Math.max(0, x) before calling limit
- Omit limit() entirely for unlimited output instead of passing -1
- Audit pagination arithmetic for off-by-one negatives (page starting at 1 vs 0)
When it happens
Trigger: Calling limit(-1, 10) or limit(0, -5) — commonly from computed/unvalidated user input or off-by-one arithmetic such as pageSize-1 with pageSize=0.
Common situations: Pagination math going negative (page=0 leading to offset=(page-1)*size); user-supplied limits clamped too late; defaults of -1 used as 'unlimited' sent straight to limit().
Related errors
- cursor must be set
- DIALECT=0 cannot be set.
- No connections available from connection provider
- No more aggregation results available
- Failed to fetch next aggregation batch
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/417f130623b79b90.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/search/aggr/CollectReducer.java:130
this.sortFields.add(SortedField.asc(field));
return this;
}
/** Convenience for {@code sortBy(SortedField.desc(field))}. */
public CollectReducer sortByDesc(String field) {
this.sortFields.add(SortedField.desc(field));
return this;
}
/** 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 {View on GitHub (pinned to 6dac31d4c2)