fix(review): stop one oversized RAG chunk from failing its whole embedding batch - #5074
Merged
Merged
Conversation
…hole embedding batch (#5072) embedTexts sent up to EMBED_BATCH (96) chunk texts to the provider in one call, so a single text exceeding the embedding model's context window (a dense/minified file, a long unbroken line) threw the whole batch out, silently dropping RAG context for every other chunk in it -- the confirmed live cause of the still-firing ai_embed_http_400 "input length exceeds the context length" errors. embedTexts now returns (number[] | null)[] | null: a null at one index means only that text failed. A batch-level throw or invalid response falls back to embedding one item at a time (sequential, not concurrent, to stay gentle on a self-hosted inference server), and upsertChunks filters out chunks that never got a vector before the index/DB write. One ERROR-level summary per degraded batch, not one per skipped item.
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5074 +/- ##
=======================================
Coverage 94.13% 94.14%
=======================================
Files 466 466
Lines 39573 39592 +19
Branches 14436 14440 +4
=======================================
+ Hits 37254 37272 +18
Misses 1664 1664
- Partials 655 656 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ai_embed_http_400) was partially fixed by fix(review): drop whitespace-only RAG chunks and surface real embed errors #5029 (empty/whitespace-only chunks), but is still firing (492 occurrences since 2026-06-28, ongoing) — now with a real error body thanks to that same PR's response-capture improvement: "the input length exceeds the context length."embedTexts(src/review/rag.ts) sends up toEMBED_BATCH(96) chunk texts to the embedding provider in ONE call. Chunking bounds by character count, not token count, and the token-per-char ratio varies a lot by content (dense/minified code, long unbroken lines) — so a single text can exceed the embedding model's context window even under the char budget. When that happens, the wholeinference.run()call throws andembedTextsreturnednullfor the entire call, discarding every other, perfectly-fine chunk in that batch (potentially from many unrelated files viaupsertChunks).embedTextsnow returns(number[] | null)[] | null: the outernullis preserved for "no adapter" / "invalid batch size" (unchanged); anullat a specific index means only that one text failed. A batch-level throw or structurally-invalid response now falls back to embedding that batch one item at a time (sequential, not concurrent, to stay gentle on a self-hosted inference server) — only the genuinely-unembeddable item(s) are lost.upsertChunksfilters out chunks whose vector came backnullbefore the vector-index/DB write.rag_embed_batch_degradedsummary per degraded batch (not one per skipped item), mirroring the per-attempt-warn/exhausted-error escalation pattern already used elsewhere in the AI-review pipeline (fix(selfhost): AI-provider per-attempt logging amplifies one retry loop into up to 6 Sentry errors #5046).Closes #5072
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #5072).Validation
git diff --checknpm run typechecknpm run test:coverage— scoped run ontest/unit/rag.test.tsshows 100% line, 99.47% branch onrag.ts(the one remaining uncovered branch, line 414, predates this diff — confirmed viagit diff origin/mainshowing it as unchanged context, not an added line). Also ran the repo'stest:changedselection (3689 tests, all green) and the full unsharded gate earlier in this session on a sibling branch off the samemain.Safety
UI Evidencesection. (N/A — backend-only.)