quarkusio/quarkus · error · PanacheQueryException
There should be no more than one result
Error message
There should be no more than one result
What it means
singleResultOptional() fetches up to 2 rows and throws PanacheQueryException when the query matches more than one document (list.size() == 2). Unlike singleResult(), an empty result is acceptable (returns Optional.empty()), but duplicate matches still violate the 'at most one' contract.
Source
Thrown at extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/CommonReactivePanacheQueryImpl.java:230
? 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));
});
}
private FindOptions buildOptions() {
FindOptions options = new FindOptions();
options.sort(sort);
if (range != null) {
// range is 0 based, so we add 1 to the limit
options.skip(range.getStartIndex()).limit(range.getLastIndex() - range.getStartIndex() + 1);
} else if (page != null) {
options.skip(page.index * page.size).limit(page.size);
}
if (projections != null) {
options.projection(this.projections);
}
if (this.collation != null) {View on GitHub (pinned to e1c734241f)
Solutions
- Create a unique index on the lookup field and clean up existing duplicates
- Narrow the query filter (e.g. add tenant or status = ACTIVE) so only one document matches
- Deduplicate data before deploying the field as a logical unique key
Example fix
// before
Optional<User> u = reactiveFind("email", email).singleResultOptional(); // throws on dupes
// after
db.users.createIndex({ email: 1 }, { unique: true, collation: { locale: 'en', strength: 2 } });
Optional<User> u = reactiveFind("email", email).singleResultOptional(); Defensive patterns
Strategy: try-catch
Try / catch
try {
return query.singleResultOptional().await().indefinitely();
} catch (PanacheQueryException e) {
// duplicates found: log entity/field and either deduplicate or use firstResult()
return Optional.empty();
} Prevention
- Back logical unique keys with MongoDB unique indexes
- Clean up duplicates before adding single-result expectations
- Consider firstResultOptional() if duplicates are tolerated in your data model
When it happens
Trigger: Calling singleResultOptional() on a query whose filter matches 2+ documents; this happens when the 'unique' field has duplicate values because MongoDB enforces no uniqueness unless an index is created.
Common situations: Duplicate records inserted before a unique index was added; case-sensitive duplicates ('Foo@x.com' vs 'foo@x.com'); soft-deleted copies of the same logical entity still present in the collection.
Related errors
- There should be only one result
- Cannot call a page related method in a ranged query, call pa
- Illegal read preference configured in the @MongoEntity anno
- Cannot sort by nulls first or nulls last
- The database was not configured for the default Mongo Client
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/488785466d182969.
Report an issue: GitHub.