Skip to content

Commit 47112fc

Browse files
authored
fix(memory): split header-too-large embedding batches
Route OpenAI/OpenAI-compatible request_headers_too_large embedding failures into the existing memory-core batch splitter instead of aborting bulk memory indexing. Tighten the classifier to require header-too-large wording rather than a bare 431 status token, so unrelated provider errors do not fan out into recursive requests. Fixes #92465. Thanks @mushuiyu886 for the fix and @BrettHamlin for the report and proof.
1 parent 8549a20 commit 47112fc

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

extensions/memory-core/src/memory/manager-embedding-policy.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,35 @@ describe("memory embedding policy", () => {
126126
expect(isRetryableMemoryEmbeddingTransportError("embedding validation failed")).toBe(false);
127127
});
128128

129+
it("splits OpenAI 431 oversized embedding batches without retrying the same request", async () => {
130+
const run = vi.fn(async (items: string[]) => {
131+
if (items.length > 1) {
132+
throw new Error(
133+
"openai embeddings failed: 431 request_headers_too_large: Request Header Fields Too Large",
134+
);
135+
}
136+
return items.map((item) => [item.charCodeAt(0)]);
137+
});
138+
139+
const result = await runMemoryEmbeddingBatchRetryWithSplit({
140+
items: ["a", "b", "c", "d"],
141+
run,
142+
isRetryable: isRetryableMemoryEmbeddingError,
143+
isSplittable: isSplittableMemoryEmbeddingTransportError,
144+
waitForRetry: async () => {},
145+
maxAttempts: 3,
146+
baseDelayMs: 500,
147+
});
148+
149+
expect(result).toEqual([[97], [98], [99], [100]]);
150+
expect(run.mock.calls.map(([items]) => items.length)).toEqual([4, 2, 1, 1, 2, 1, 1]);
151+
expect(isRetryableMemoryEmbeddingError("431 request_headers_too_large")).toBe(false);
152+
expect(isSplittableMemoryEmbeddingTransportError("431 request_headers_too_large")).toBe(true);
153+
expect(
154+
isSplittableMemoryEmbeddingTransportError("embedding validation failed at item 4312"),
155+
).toBe(false);
156+
});
157+
129158
it("retries too-many-tokens-per-day errors", async () => {
130159
let calls = 0;
131160
const waits: number[] = [];

extensions/memory-core/src/memory/manager-embedding-policy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const RETRYABLE_MEMORY_EMBEDDING_TRANSPORT_ERROR_RE =
8888
/(fetch failed|other side closed|ECONNRESET|ECONNREFUSED|ETIMEDOUT|EPIPE|UND_ERR_|socket hang up|socket terminated|network error|read ECONN|timed out|connection (?:reset|refused|aborted|timed out)|EHOSTUNREACH|ENETUNREACH|ECONNABORTED|EAI_AGAIN)/i;
8989

9090
const SPLITTABLE_MEMORY_EMBEDDING_TRANSPORT_ERROR_RE =
91-
/(other side closed|ECONNRESET|EPIPE|UND_ERR_SOCKET|socket hang up|socket terminated|read ECONN|connection (?:reset|aborted))/i;
91+
/(request_headers_too_large|request header fields too large|other side closed|ECONNRESET|EPIPE|UND_ERR_SOCKET|socket hang up|socket terminated|read ECONN|connection (?:reset|aborted))/i;
9292

9393
export function isRetryableMemoryEmbeddingTransportError(message: string): boolean {
9494
return RETRYABLE_MEMORY_EMBEDDING_TRANSPORT_ERROR_RE.test(message);

0 commit comments

Comments
 (0)