quarkusio/quarkus · error · IllegalStateException
Cannot combine `IDLE` and `TIME`
Error message
Cannot combine `IDLE` and `TIME`
What it means
XCLAIM can set the delivery time of claimed messages either as a relative IDLE (milliseconds since now) or an absolute TIME (unix ms), but not both. XClaimArgs.toArgs() throws IllegalStateException when idle was set and time > 0 is also present, as the two are redundant/contradictory.
Source
Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/stream/XClaimArgs.java:107
* Sets the last id of the message to claim.
*
* @param lastId the last id, must not be {@code null}
* @return the current {@code XClaimArgs}
*/
public XClaimArgs lastId(String lastId) {
this.lastId = lastId;
return this;
}
@Override
public List<Object> toArgs() {
List<Object> args = new ArrayList<>();
if (idle != null) {
args.add("IDLE");
args.add(Long.toString(idle.toMillis()));
if (time > 0) {
throw new IllegalStateException("Cannot combine `IDLE` and `TIME`");
}
}
if (time > 0) {
args.add("TIME");
args.add(Long.toString(time));
}
if (retryCount > 0) {
args.add("RETRYCOUNT");
args.add(Integer.toString(retryCount));
}
if (force) {
args.add("FORCE");
}
if (justId) {View on GitHub (pinned to e1c734241f)
Solutions
- Keep only one: use .idle(Duration) for relative delay or .time(long) for absolute timestamp
- Set the unused field to 0/null before building args
- Derive one from the other if both inputs exist (e.g. idle = time - now) and set only idle
Example fix
// before XClaimArgs args = new XClaimArgs().idle(Duration.ofSeconds(1)).time(System.currentTimeMillis()); // after XClaimArgs args = new XClaimArgs().idle(Duration.ofSeconds(1));
Defensive patterns
Strategy: validation
Validate before calling
if (idle != null && time > 0) throw new IllegalArgumentException("XCLAIM accepts IDLE or TIME, not both"); Try / catch
try {
stream.xclaim(key, group, consumer, minIdle, ids, args);
} catch (IllegalStateException e) {
// rebuild XClaimArgs with only idle or only time
} Prevention
- Choose one time model (relative IDLE vs absolute TIME) per use case
- Convert between them explicitly: idle = Duration.ofMillis(time - now)
- Zero-out the unused option when loading settings from config
When it happens
Trigger: Calling xclaimArgs().idle(Duration.ofSeconds(1)) and .time(epochMs) on the same instance; or time defaulting to a positive value while idle is also set.
Common situations: Config exposing both 'idle' and 'time' options and both being applied; migrating code from TIME-based to IDLE-based claims leaving the old field set; builder reuse.
Related errors
- Cannot use `MAXLEN` and `MINID` together
- Cannot set XX and NX together
- BYRADIUS and BYBOX cannot be used together
- Cannot specify both `includes` and `excludes` terms
- Cannot use XX and NX together
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5159e51a3d2e8d23.
Report an issue: GitHub.