{"record":{"id":"87885add4659669d","repo":"abhigyanpatwari/GitNexus","slug":"err-terminalmessage-terminal-2xx-body-error","errorCode":null,"errorMessage":"err.terminalMessage (terminal 2xx body error)","messagePattern":"err\\.terminalMessage \\(terminal 2xx body error\\)","errorType":"exception","errorClass":"HttpEmbeddingError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/embeddings/http-client.ts","lineNumber":553,"sourceCode":"          sleep: (ms) => abortableSleep(ms, requestOptions.signal),\n        },\n      },\n    );\n  } catch (err) {\n    if (\n      requestOptions.signal?.aborted ||\n      (err instanceof DOMException && err.name === 'AbortError')\n    ) {\n      throw new HttpEmbeddingError(\n        `Embedding request cancelled (${safeUrl(url)}, batch ${batchIndex})`,\n        { cause: err },\n      );\n    }\n    // Retries are exhausted on a bad 2xx body. Surface the message the sentinel\n    // 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      );","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/embeddings/http-client.ts#L535-L571","documentation":"httpEmbedBatch retries requests whose 2xx body cannot be parsed/validated (RetryableEmbeddingBodyError). When retries are exhausted, it throws HttpEmbeddingError whose message is err.terminalMessage — a sanitized sentinel message — with the underlying parse error preserved only in cause. This deliberately keeps raw body text out of the top-level message so it cannot leak to stderr via sanitizeReason fallbacks.","triggerScenarios":"Calling the HTTP embedding client against an endpoint that returns HTTP 200 with a body that is not the expected embedding JSON (HTML error page, proxy interstitial, wrong schema) on every attempt until maxAttempts is reached.","commonSituations":"Reverse proxy or API gateway returning an HTML login/error page with status 200; embedding server version returning a different response schema; misconfigured EMBED_URL pointing at a non-embedding service.","solutions":["Inspect err.cause — it holds the real parse error showing what the body actually looked like structurally.","Verify the endpoint URL actually serves the embedding API and not a proxy/login page (curl the URL).","Check the embedding server version matches the client's expected response schema; upgrade or reconfigure.","Confirm the server is healthy; a 200-with-HTML usually means a gateway misroute."],"exampleFix":"// before: URL points at a gateway root\nconst url = 'https://gw.internal/';\n// after: full embedding API path\nconst url = 'https://gw.internal/embeddings/v1/embed';","handlingStrategy":"try-catch","validationCode":"// verify the endpoint returns JSON embedding responses before batch use\nconst probe = await fetch(url, { method: 'POST', headers });\nconst ct = probe.headers.get('content-type') ?? '';\nif (!ct.includes('application/json')) throw new Error(`EMBED_URL returns ${ct}; expected JSON`);","typeGuard":null,"tryCatchPattern":"try {\n  vectors = await httpEmbedBatch(items, opts);\n} catch (e) {\n  if (e instanceof HttpEmbeddingError && e.cause) {\n    console.error('Embedding body parse failed; underlying:', e.cause); // body shape info in cause\n  }\n  throw e;\n}","preventionTips":["Curl the endpoint once and confirm it returns the expected JSON embedding schema.","Point EMBED_URL at the embedding API route, not a gateway root or login page.","Version-check the embedding server against the client's expected response schema.","Alert on non-JSON content-types from the endpoint in monitoring."],"tags":["embeddings","http","invalid-response-body","retry-exhausted"],"backgroundTag":"invalid-json-response","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}