Repository navigation
fix(embedding): recover truncated responses and validate vectors - #277
Conversation
ReviewThe issue is valid, and the root-cause analysis checks out. In reqwest 0.12.28 (the version in our
Main concern: a truncated body without Content-Length is still not retriedThe truncation fixtures always send That is the same truncation scenario #275 suspects, but it fails immediately. Suggested fix: treat match serde_json::from_slice::<EmbedResponse>(&bytes) {
Ok(r) => return Ok(r),
Err(e) if matches!(e.classify(), Category::Eof | Category::Io) => {
last_err = "embedding response body was truncated".into();
continue;
}
Err(e) => return Err(/* schema / JSON as now */),
}Please add a test for this case too, e.g. a Minor / optional
The part of #275 about the precommit outcome contract and idempotency stays out of scope, and the PR description already says so with |
Re-review of
|
What type of PR is this?
Which issue(s) this PR fixes
Related: #275 (HTTP client portion); owner-scoped idempotency and a structured precommit outcome remain separate work.
What this PR does / why we need it
An interrupted embedding response previously exited the retry loop after HTTP headers arrived, aborting memory ingestion even when the next embedding attempt could succeed. Read the body separately from JSON parsing and retry body-read failures and JSON EOF/IO within the existing three-attempt budget, before memory persistence. This includes partial JSON in responses without Content-Length and in chunked responses.
JSON Syntax/Data failures and nonretryable HTTP errors fail promptly. Existing 5xx/429 retries remain unchanged. Return stable timeout, connection, request-body, response-body, and parse classifications without exposing upstream bodies, unexpected JSON values, request URLs, or credentials. HTTP status remains available for non-success responses; raw or truncated provider-body logging is intentionally omitted because it may reveal sensitive values.
Validate response count and every vector's configured dimension before returning single or batch results. When indexes are supplied, require a complete, unique 0..N-1 set and return vectors in input order. Providers that omit all indexes remain compatible and retain response order; their semantic ordering cannot be checked without indexes. Mixed, duplicate, and out-of-range indexes fail promptly.
The retry budget is three attempts with a 30-second request timeout and 200/400 ms backoff (approximately 90.6 seconds of request/backoff budget); semaphore acquisition is separate, defaulting to five seconds. This is not a new end-to-end deadline.
This addresses the confirmed HTTP-client retry gap and response validation. It does not replay memory writes, add an atomic idempotency/precommit contract, or establish the cause of the original live provider response.
Validation
cargo test --offline -p memoria-embedding --lib: 37 passed, including 18 loopback HTTP/client tests.--all-targets -- -D warnings), rustfmt, andgit diff --check: passed.