quarkusio/quarkus · error · IllegalArgumentException

Cannot use descending and ascending order at the same time

Error message

Cannot use descending and ascending order at the same time

What it means

A FT.SEARCH SORTBY clause can only specify one sort direction. QueryArgs.toArgs() throws IllegalArgumentException when both ascending(...) and descending(...) were set on the same QueryArgs, since SORTBY <field> ASC|DESC accepts a single direction.

Source

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

            list.add("LANGUAGE");
            list.add(lang);
        }
        if (expander != null) {
            list.add("EXPANDER");
            list.add(expander);
        }
        if (scorer != null) {
            list.add("SCORER");
            list.add(scorer);
        }

        if (explainScore) {
            list.add("EXPLAINSCORE");
        }

        if (asc != null || desc != null) {
            if (asc != null && desc != null) {
                throw new IllegalArgumentException("Cannot use descending and ascending order at the same time");
            }
            list.add("SORTBY");
            if (asc != null) {
                list.add(asc);
                list.add("ASC");
            }
            if (desc != null) {
                list.add(desc);
                list.add("DESC");
            }
        }

        if (offset != -1) {
            list.add("LIMIT");
            list.add(Integer.toString(offset));
            list.add(Integer.toString(count));
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set only one of ascending() or descending() per QueryArgs
  2. Use if/else so exactly one direction is applied
  3. Create a fresh QueryArgs per request rather than reusing a mutated instance

Example fix

// before
QueryArgs args = new QueryArgs();
if (asc) args.ascending("ts");
if (!asc) args.descending("ts"); // both set when asc flag logic is buggy
// after
QueryArgs args = asc ? new QueryArgs().ascending("ts") : new QueryArgs().descending("ts");
Defensive patterns

Strategy: validation

Validate before calling

if (sortAsc != null && sortDesc != null) throw new IllegalStateException("Specify at most one sort direction in QueryArgs");
QueryArgs args = new QueryArgs();
if (sortAsc != null) args.ascending(sortAsc); else if (sortDesc != null) args.descending(sortDesc);

Type guard

boolean validSort(String asc, String desc) {
    return asc == null || desc == null;
}

Try / catch

try {
    ft.search(query, args);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("descending and ascending")) {
        throw new IllegalStateException("QueryArgs must not set both ascending() and descending()", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling queryArgs.ascending("field") and descending("field") (on the same or different fields) on one QueryArgs instance before ft().search(), typically from conditional building where both branches executed.

Common situations: Conditional sort logic (if sortAsc ... else sortDesc) written so both setters run; reusing a QueryArgs instance across requests and mutating its direction; wanting multi-field sort and assuming asc+desc calls accumulate instead of conflict.

Related errors


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