quarkusio/quarkus · error · IllegalArgumentException
Cannot set XX and NX together
Error message
Cannot set XX and NX together
What it means
GeoAddArgs.toArgs() serializes GEOADD options and enforces Redis's rule that XX (only update existing members) and NX (only add new members) are mutually exclusive. Setting both flags on the same GeoAddArgs throws this IllegalArgumentException when the command is built by cmd().
Source
Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoAddArgs.java:47
public GeoAddArgs xx() {
this.xx = true;
return this;
}
/**
* Modify the return value from the number of new elements added, to the total number of elements changed.
* (CH is an abbreviation of changed).
*
* @return the current {@code GeoaddArgs}
**/
public GeoAddArgs ch() {
this.ch = true;
return this;
}
public List<Object> toArgs() {
if (xx && nx) {
throw new IllegalArgumentException("Cannot set XX and NX together");
}
List<Object> args = new ArrayList<>();
if (xx) {
args.add("XX");
}
if (nx) {
args.add("NX");
}
if (ch) {
args.add("CH");
}
return args;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Choose one: use xx() to only update existing members, or nx() to only add new ones — not both.
- If flags come from config, validate that at most one is true and pick a precedence before building args.
- Remove the redundant flag call from the fluent chain.
Example fix
// before GeoAddArgs args = GeoAddArgs.Builder.geoAddArgs().xx().nx(); // throws in toArgs // after GeoAddArgs args = updateExisting ? GeoAddArgs.Builder.geoAddArgs().xx() : GeoAddArgs.Builder.geoAddArgs().nx();
Defensive patterns
Strategy: validation
Validate before calling
if (updateExisting && onlyAddNew) {
throw new IllegalArgumentException("GEOADD XX and NX are mutually exclusive; pick one");
}
GeoAddArgs a = GeoAddArgs.Builder.geoAddArgs();
if (updateExisting) a.xx(); else if (onlyAddNew) a.nx(); Try / catch
try { return geo.geoadd(args, members); } catch (IllegalArgumentException e) { if (e.getMessage().contains("XX and NX")) { args = GeoAddArgs.Builder.geoAddArgs().nx(); return geo.geoadd(args, members); } throw e; } Prevention
- Never chain .xx() and .nx() on the same GeoAddArgs.
- If driven by config flags, enforce mutual exclusivity at config validation time.
- Decide precedence (update wins vs add wins) once and encode it in a helper method.
When it happens
Trigger: Calling geoAddArgs.xx().nx() (or the chained equivalents) on the same args object before passing it to geoadd(); also when flags are set conditionally from two different config flags that happen to both be true.
Common situations: Copying a fluent chain and leaving both xx() and nx() in it; combining two feature flags (updateExisting + addNewOnly) that can both be enabled in config; merging args objects built in different code paths.
Related errors
- BYRADIUS and BYBOX cannot be used together
- The longitude must be in [-180, 180]
- The latitude must be in [85.05112878, 85.05112878]
- ANY can only be used if COUNT is also set
- ANY can only be used if COUNT is also set
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e26819aa3141dff6.
Report an issue: GitHub.