quarkusio/quarkus · error · IllegalArgumentException

Cannot use `ON HASH` and `ON JSON` at the same time

Error message

Cannot use `ON HASH` and `ON JSON` at the same time

What it means

RediSearch FT.CREATE allows only one ON <type> clause selecting the data structure to index. CreateArgs.toArgs() throws IllegalArgumentException when both onHash and onJson were requested, because the generated ON HASH ON JSON command would be invalid.

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/search/CreateArgs.java:297

    /**
     * Adds a field to the schema.
     *
     * @param field the field
     * @param alias the alias, can be {@code null}
     * @param type the field type
     * @return the current {@code CreateArgs}
     */
    public CreateArgs indexedField(String field, String alias, FieldType type) {
        return indexedField(field, alias, type, null);
    }

    @Override
    public List<Object> toArgs() {
        List<Object> list = new ArrayList<>();

        if (onHash) {
            if (onJson) {
                throw new IllegalArgumentException("Cannot use `ON HASH` and `ON JSON` at the same time");
            }
            list.add("ON");
            list.add("HASH");
        }

        if (onJson) {
            list.add("ON");
            list.add("JSON");
        }

        if (prefixes != null && prefixes.length > 0) {
            list.add("PREFIX");
            list.add(Integer.toString(prefixes.length));
            list.addAll(Arrays.asList(prefixes));
        }

        if (filter != null) {
            list.add("FILTER");

View on GitHub (pinned to e1c734241f)

Solutions

  1. Call exactly one of onHash() or onJson() on the CreateArgs
  2. Create two separate indexes if both hash and JSON documents must be indexed
  3. Check conditional building logic so only one branch sets the ON type

Example fix

// before
CreateArgs args = new CreateArgs().onHash();
if (useJson) args.onJson(); // throws when useJson is true
// after
CreateArgs args = useJson ? new CreateArgs().onJson() : new CreateArgs().onHash();
Defensive patterns

Strategy: validation

Validate before calling

if (indexHash && indexJson) throw new IllegalStateException("Create one index per document type; ON HASH and ON JSON cannot be combined");
CreateArgs args = indexJson ? new CreateArgs().onJson() : new CreateArgs().onHash();

Type guard

boolean validOnType(CreateArgs args, boolean onHash, boolean onJson) {
    return !(onHash && onJson);
}

Try / catch

try {
    ft.create(index, args, schema);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("ON HASH")) {
        throw new IllegalStateException("Index must target exactly one document type", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ft().create(index, new CreateArgs().onHash().onJson(), schema) — i.e. chaining both onHash() and onJson() on the same CreateArgs instance, typically from conditional building code that sets both flags from user/config input.

Common situations: Trying to index both hash and JSON documents with a single index; conditional builder code where two branches both fire instead of being exclusive; migrating code where the storage type switched but the old onHash() call was left in place.

Related errors


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