Detail Bug Report
https://app.detail.dev/org_befd6425-a158-4e24-9d4d-1e5c08769515/bugs/bug_c1e3e808-e251-46eb-8bad-9b4714c18c54
Introduced in #141 by @WilliamAGH on Jul 27, 2026
Summary
- Context: Hybrid search retrieves documents from multiple Qdrant collections and originally supported configurable partial failure handling via
failOnPartialSearchError property
- Bug: Refactoring in commit 4130ba2 removed conditional failure logic and made the throw unconditional, leaving
toNotice() method and SearchOutcome.notices field as dead code
- Actual vs. expected: Code should support partial failures (original design); instead it always throws, breaking original intent
- Impact: Users lose all search results when one collection fails; retry mechanism retries entire operation rather than proceeding with partial results
Code with Bug
HybridSearchService.java:
if (!collectionFailures.isEmpty()) {
throw new HybridSearchPartialFailureException(
"Qdrant retrieval failed for " + collectionFailures.size() + " collection(s)",
collectionFailures,
dependencyFailures);
// <-- BUG 🔴 unconditional throw prevents returning partial results + notices
}
List<Document> rankedDocuments = scoredPointsByUuid.values().stream()
.sorted(Comparator.comparingDouble(ScoredPointMatch::score).reversed())
.limit(topK)
.map(scoredPointMatch -> QdrantScoredPointDocumentMapper.toDocument(
scoredPointMatch.point(),
scoredPointMatch.id(),
scoredPointMatch.score(),
scoredPointMatch.collectionName()))
.toList();
List<HybridSearchNotice> retrievalNotices =
collectionFailures.stream().map(HybridSearchService::toNotice).toList(); // <-- BUG 🔴 unreachable
return new SearchOutcome(rankedDocuments, retrievalNotices);
Explanation
- The service collects per-collection failures (
collectionFailures) during fan-out.
- Current code throws
HybridSearchPartialFailureException whenever any collection fails, even if other collections succeeded and there are ranked documents to return.
- This makes the downstream “notices” pipeline unreachable:
HybridSearchService::toNotice exists and is referenced, but the code path can never reach it due to the unconditional throw.
- Git history shows this is a regression: the earlier implementation conditionally threw based on a failure policy /
failOnPartialSearchError, allowing partial results + notices when configured.
Codebase Inconsistency
The codebase contains a full propagation path for retrieval notices, implying HybridSearchService is expected to return partial results with notices in some cases:
RetrievalService.java:
retrievedDocuments.addAll(searchOutcome.documents());
searchOutcome.notices().stream()
.map(searchNotice -> new RetrievalNotice(searchNotice.summary(), searchNotice.details()))
.forEach(retrievalNotices::add);
This pipeline is effectively orphaned because HybridSearchService never produces notices.
Recommended Fix
Restore conditional failure behavior so partial successes can return documents plus notices (at minimum: only throw when no documents were retrieved):
if (!collectionFailures.isEmpty()) {
boolean allCollectionsFailed = scoredPointsByUuid.isEmpty();
if (allCollectionsFailed) {
throw new HybridSearchPartialFailureException(
"Qdrant retrieval failed for " + collectionFailures.size() + " collection(s)",
collectionFailures,
dependencyFailures);
}
// Otherwise continue with partial results and include notices
}
List<HybridSearchNotice> retrievalNotices =
collectionFailures.stream().map(HybridSearchService::toNotice).toList();
return new SearchOutcome(rankedDocuments, retrievalNotices);
History
This bug was introduced in commit 4130ba2. The original implementation (commit dc1a952) correctly used a conditional failure policy: if (!collectionFailures.isEmpty() && failOnPartialSearchError), which allowed the search to continue with degraded results and notices when the policy was disabled. Commit 4130ba2 removed the failOnPartialSearchError condition, making the throw unconditional and rendering the entire notices pipeline unreachable.
Detail Bug Report
https://app.detail.dev/org_befd6425-a158-4e24-9d4d-1e5c08769515/bugs/bug_c1e3e808-e251-46eb-8bad-9b4714c18c54
Introduced in #141 by @WilliamAGH on Jul 27, 2026
Summary
failOnPartialSearchErrorpropertytoNotice()method andSearchOutcome.noticesfield as dead codeCode with Bug
HybridSearchService.java:Explanation
collectionFailures) during fan-out.HybridSearchPartialFailureExceptionwhenever any collection fails, even if other collections succeeded and there are ranked documents to return.HybridSearchService::toNoticeexists and is referenced, but the code path can never reach it due to the unconditional throw.failOnPartialSearchError, allowing partial results + notices when configured.Codebase Inconsistency
The codebase contains a full propagation path for retrieval notices, implying
HybridSearchServiceis expected to return partial results with notices in some cases:RetrievalService.java:This pipeline is effectively orphaned because
HybridSearchServicenever produces notices.Recommended Fix
Restore conditional failure behavior so partial successes can return documents plus notices (at minimum: only throw when no documents were retrieved):
History
This bug was introduced in commit 4130ba2. The original implementation (commit dc1a952) correctly used a conditional failure policy:
if (!collectionFailures.isEmpty() && failOnPartialSearchError), which allowed the search to continue with degraded results and notices when the policy was disabled. Commit 4130ba2 removed thefailOnPartialSearchErrorcondition, making the throw unconditional and rendering the entire notices pipeline unreachable.