fix: hybrid retrieval graceful degradation with Promise.allSettled#581
fix: hybrid retrieval graceful degradation with Promise.allSettled#581ether-btc wants to merge 1 commit intoCortexReach:masterfrom
Conversation
Replace Promise.all with Promise.allSettled in hybridRetrieval() so that if either vector or BM25 search throws, the other search's results are still used instead of failing the entire query. Behavior: - One search fails → other search results returned, failed side logged - Both fail → throws with failureStage=hybrid.parallelSearch - Diagnostics correctly reflect 0 for failed search counts Fixes Bug 3 from community code audit.
rwmjhb
left a comment
There was a problem hiding this comment.
Thanks for the fix — switching to Promise.allSettled is the right approach here. One blocking issue to address before merge:
Must Fix
F1 — Both-fail guard triggers on legitimate zero-result queries (src/retriever.ts:954)
// Current (incorrect)
if (vectorResults.length === 0 && bm25Results.length === 0) {
throw attachFailureStage(new Error('both vector and BM25 search failed'), ...)
}This condition fires when both backends succeed but return no matches — any sparse knowledge base or narrow query now throws "both vector and BM25 search failed" instead of returning []. It also masks single-backend failures: if one rejects and the other legitimately returns [], the wrong branch fires.
Fix: guard on settled status, not array length:
if (vectorResult_.status === 'rejected' && bm25Result_.status === 'rejected') {
throw attachFailureStage(new Error('both vector and BM25 search failed'), ...)
}Nice to Have
-
F2 (
src/retriever.ts:955): The both-fail path discards original error context —vectorResult_.reasonandbm25Result_.reasonareconsole.warn'd but not propagated into the thrown error. ConsiderAggregateError([vectorResult_.reason, bm25Result_.reason], 'both searches failed')or embedding.messagestrings directly, so on-call diagnostics show why each backend failed. -
EF2: None of the three new degradation branches (vector-fail, BM25-fail, both-fail) are covered by tests. The F1 regression in particular can't be caught by the existing test suite. Worth adding a test that injects a rejected backend alongside an empty-result fulfilled backend.
-
EF4: Base is stale — please rebase on current
mainbefore merge.src/retriever.tsis a high-risk module with active concurrent changes.
Overall direction is good — this is worth merging once the length-vs-status guard is corrected.
Bug 3: Hybrid Promise.all no fallback
Reported in community code audit
Problem
In , runs and in parallel. If either throws (e.g., FTS index corruption for BM25), the entire hybrid search fails — vector results are lost with no graceful degradation.
Fix
Replace with :
Testing
Files changed
Audit reference: memory-lancedb-pro code audit — Bug 3, reported 2026-04-11