quarkusio/quarkus · error · IllegalArgumentException
Cannot use XX and NX together
Error message
Cannot use XX and NX together
What it means
ZADD supports the XX (only update existing) and NX (only add new) modifiers, but they are semantically contradictory: an element cannot be both already present and absent. The library detects both flags set in ZAddArgs.toArgs() and throws before the command is sent.
Source
Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/sortedset/ZAddArgs.java:74
this.lt = true;
return this;
}
/**
* Only update existing elements if the new score is greater than the current score.
* This flag doesn't prevent adding new elements.
*
* @return the current {@code ZAddArgs}
**/
public ZAddArgs gt() {
this.gt = true;
return this;
}
@Override
public List<Object> toArgs() {
if (xx && nx) {
throw new IllegalArgumentException("Cannot use XX and NX together");
}
if (lt && gt) {
throw new IllegalArgumentException("Cannot use LT and GT together");
}
List<Object> args = new ArrayList<>();
putFlag(args, nx, "NX");
putFlag(args, xx, "XX");
putFlag(args, lt, "LT");
putFlag(args, gt, "GT");
putFlag(args, ch, "CH");
return args;
}
public void putFlag(List<Object> args, boolean value, String flag) {
if (value) {
args.add(flag);
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove one of the two calls: use .xx() to update-only or .nx() to add-only
- Create a fresh ZAddArgs instance per operation instead of sharing/reusing one
- Wrap flag-setting logic so setting one clears the other
Example fix
// before ZAddArgs args = new ZAddArgs().xx().nx(); // after ZAddArgs args = new ZAddArgs().nx(); // add-only (or .xx() for update-only)
Defensive patterns
Strategy: validation
Validate before calling
if (wantExistingOnly && wantNewOnly) throw new IllegalArgumentException("Choose XX or NX for ZADD, not both"); Try / catch
try {
sortedSet.zadd(key, score, member, args);
} catch (IllegalArgumentException e) {
// recreate ZAddArgs with a single flag
} Prevention
- Use a fresh ZAddArgs per operation; never share builders
- Represent XX/NX as one enum (UpdatePolicy.EXISTING | NEW) rather than two booleans
- Add unit tests asserting the toArgs() output for each flag combo
When it happens
Trigger: Calling zaddArgs.xx().nx() (in either order) on ZAddArgs, then passing it to a zadd/increment operation.
Common situations: Builder reuse: one code path sets XX, another sets NX on the same shared args object; misunderstanding flags as independent toggles.
Related errors
- Cannot use LT and GT together
- Cannot use MIN and MAX together
- Cannot set XX and NX together
- BYRADIUS and BYBOX cannot be used together
- Cannot specify both `includes` and `excludes` terms
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/88a445b38df89aeb.
Report an issue: GitHub.