quarkusio/quarkus · error · PanacheQueryException

There should be only one result

Error message

There should be only one result

What it means

singleResult() fetches up to 2 rows (buildOptions(2)) and throws PanacheQueryException unless exactly one entity is returned. It exists for queries that must, by domain rules, match exactly one document; zero results or two-plus results are both treated as errors rather than silently returning null or the first row.

Source

Thrown at extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/CommonReactivePanacheQueryImpl.java:216

    }

    public <T extends Entity> Uni<Optional<T>> firstResultOptional() {
        FindOptions options = buildOptions(1);
        Multi<T> results = Panache.getCurrentSession() != null
                ? collection.find(Panache.getCurrentSession(), getQuery(), options)
                : collection.find(getQuery(), options);
        return results.collect().first().map(o -> Optional.ofNullable(o));
    }

    @SuppressWarnings("unchecked")
    public <T extends Entity> Uni<T> singleResult() {
        FindOptions options = buildOptions(2);
        Multi<T> results = Panache.getCurrentSession() != null
                ? collection.find(Panache.getCurrentSession(), getQuery(), options)
                : collection.find(getQuery(), options);
        return results.collect().asList().map(list -> {
            if (list.size() != 1) {
                throw new PanacheQueryException("There should be only one result");
            } else {
                return list.get(0);
            }
        });
    }

    public <T extends Entity> Uni<Optional<T>> singleResultOptional() {
        FindOptions options = buildOptions(2);
        Multi<T> results = Panache.getCurrentSession() != null
                ? collection.find(Panache.getCurrentSession(), getQuery(), options)
                : collection.find(getQuery(), options);
        return results.collect().asList().map(list -> {
            if (list.size() == 2) {
                throw new PanacheQueryException("There should be no more than one result");
            }
            return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0));
        });
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check whether zero results are legitimate and switch to singleResultOptional() or firstResult() if an empty match is acceptable
  2. Add a unique index on the filter field (or use upsert semantics) to guarantee at most one document
  3. Narrow the filter criteria so exactly one document matches, and verify you are connected to the intended database/collection

Example fix

// before
Item item = reactiveFind("code", code).singleResult(); // throws if missing

// after
Optional<Item> item = reactiveFind("code", code).singleResultOptional().await().indefinitely();
Defensive patterns

Strategy: validation

Validate before calling

long count = reactiveCount("code", code).await().indefinitely();
if (count != 1) {
    throw new IllegalStateException("Expected exactly 1 item for code=" + code + ", found " + count);
}

Try / catch

try {
    return query.singleResult().await().indefinitely();
} catch (PanacheQueryException e) {
    // 0 or >1 matches; inspect count or fall back to firstResult
    return null;
}

Prevention

When it happens

Trigger: Calling singleResult() on a query whose filter matches 0 documents (list.size() != 1) or more than 1 document.

Common situations: Lookup by a field expected to be unique (email, code) that is not actually uniquely indexed in MongoDB, so duplicates were inserted; querying before the record exists (race or wrong tenant/database); overly broad filter matching several documents.

Related errors


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