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

  1. Choose one: use xx() to only update existing members, or nx() to only add new ones — not both.
  2. If flags come from config, validate that at most one is true and pick a precedence before building args.
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/e26819aa3141dff6. Report an issue: GitHub.