{"record":{"id":"fba250858298381c","repo":"abhigyanpatwari/GitNexus","slug":"embedding-request-timed-out-after-timeoutms-ms","errorCode":null,"errorMessage":"Embedding request timed out after ${timeoutMs}ms (${safeUrl(url)}, batch ${batchIndex})","messagePattern":"Embedding request timed out after (.+?)ms \\((.+?), batch (.+?)\\)","errorType":"exception","errorClass":"HttpEmbeddingError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/embeddings/http-client.ts","lineNumber":568,"sourceCode":"    // carried, keeping the underlying parse error in `cause` only — the body\n    // text must never reach the `sanitizeReason` fallback and leak to stderr.\n    if (err instanceof RetryableEmbeddingBodyError) {\n      throw new HttpEmbeddingError(err.terminalMessage, { cause: err.cause });\n    }\n    if (err instanceof RetryableEmbeddingTimeoutError) {\n      throw new HttpEmbeddingError(\n        `${err.message} after ${maxAttempts} attempt(s) (${safeUrl(url)}, batch ${batchIndex})`,\n        { cause: err.cause },\n      );\n    }\n    if (err instanceof CircuitOpenError) {\n      throw new HttpEmbeddingError(\n        `Embedding endpoint circuit open (${safeUrl(url)}, batch ${batchIndex}): retry in ${Math.ceil(err.retryAfterMs / 1000)}s`,\n        { cause: err },\n      );\n    }\n    if (err instanceof DOMException && err.name === 'TimeoutError') {\n      throw new HttpEmbeddingError(\n        `Embedding request timed out after ${timeoutMs}ms (${safeUrl(url)}, batch ${batchIndex})`,\n        { cause: err },\n      );\n    }\n    if (err instanceof ResilientFetchExhaustedError) {\n      throw new HttpEmbeddingError(\n        `Embedding endpoint returned ${err.response.status} (${safeUrl(url)}, batch ${batchIndex})`,\n        { cause: err },\n      );\n    }\n    const reason = sanitizeReason(err instanceof Error ? err.message : String(err), url, apiKey);\n    const safeCause = new Error(reason);\n    safeCause.name = err instanceof Error ? err.name : 'EmbeddingTransportError';\n    throw new HttpEmbeddingError(\n      `Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason}`,\n      { cause: safeCause },\n    );\n  }","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/embeddings/http-client.ts#L550-L586","documentation":"httpEmbedBatch maps a DOMException TimeoutError to this message: the per-request HTTP timeout (GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS, default 180000 ms, cap 300000 ms) expired while awaiting the endpoint. The abort signal wired to the body stream rejects with the timeout reason, which is preserved as the classification rather than being wrapped into a retryable body error.","triggerScenarios":"An embedding endpoint slower than the configured timeout for a given batch — cold-starting models, oversized batches, or network high latency — such that headers/body don't complete within timeoutMs.","commonSituations":"Self-hosted models (Ollama/llama.cpp) loading on first request, giant repositories producing large batches, CI runners with slow egress, default 180s exceeded only occasionally.","solutions":["Raise the timeout: export GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS=300000 (300s is the hard cap).","Reduce batch size so each request completes faster.","Warm up the model server (one manual curl) before running the pipeline.","Move the endpoint closer / fix network latency; check server-side request logs for slow batches."],"exampleFix":"# before (default 180s too short for cold model)\n# after\nexport GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS=300000","handlingStrategy":"retry","validationCode":"const timeoutMs = Number(process.env.GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS ?? 180_000);\nconst estimatedWorstBatchMs = texts.length * perTextBudgetMs;\nif (estimatedWorstBatchMs > timeoutMs) {\n  process.env.GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS = '300000'; // or split the batch\n}","typeGuard":"const isEmbeddingTimeout = (e: unknown): boolean =>\n  e instanceof Error && /Embedding request timed out after \\d+ms/.test(e.message);","tryCatchPattern":"try {\n  vectors = await httpEmbed(texts);\n} catch (e) {\n  if (isEmbeddingTimeout(e)) {\n    const half = Math.ceil(texts.length / 2);\n    const [a, b] = [texts.slice(0, half), texts.slice(half)];\n    vectors = [...await httpEmbed(a), ...await httpEmbed(b)]; // smaller batches\n  } else throw e;\n}","preventionTips":["Warm self-hosted model servers with a single-request curl before batch runs.","Set GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS (≤300000) to a realistic p99 batch latency.","Prefer smaller batches over bigger timeouts when the endpoint is cold or slow."],"tags":["embeddings","http","timeout","latency"],"backgroundTag":"request-timeout","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}