{"record":{"id":"b750d553eaf69212","repo":"abhigyanpatwari/GitNexus","slug":"embedding-request-failed-safeurl-url-batch","errorCode":null,"errorMessage":"Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason}","messagePattern":"Embedding request failed \\((.+?), batch (.+?)\\): (.+?)","errorType":"exception","errorClass":"HttpEmbeddingError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/embeddings/http-client.ts","lineNumber":527,"sourceCode":"        { 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  }\n\n  if (!resp.ok) {\n    // resilientFetch already retried 5xx/429; any non-OK response here is\n    // a terminal client error (4xx other than 429).\n    throw new HttpEmbeddingError(\n      `Embedding endpoint returned ${resp.status} (${safeUrl(url)}, batch ${batchIndex})`,\n    );\n  }\n\n  if (parsed === undefined) {\n    // Defensively unreachable: an OK response either sets `parsed` or throws\n    // out of `fetchImpl`. Kept so the narrowing holds without a non-null\n    // assertion, and so a future `resilientFetch` change can't return an\n    // unvalidated body silently.","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/embeddings/http-client.ts#L509-L545","documentation":"An HttpEmbeddingError thrown from httpEmbedBatch's catch block as the generic fallback for any error that is not an abort, a RetryableEmbeddingBodyError, a CircuitOpenError, a TimeoutError, or a ResilientFetchExhaustedError. The underlying reason is run through sanitizeReason (which strips URL credentials and the API key) before being interpolated, and the cause's name is preserved on a sanitized cause Error. This is the catch-all for transport-level failures (DNS, connection refused, TLS) that resilientFetch did not classify as retryable.","triggerScenarios":"httpEmbedBatch's resilientFetch throws an error matching none of the typed branches. Concrete cases: ENOTFOUND / EAI_AGAIN (DNS failure), ECONNREFUSED (nothing listening), TLS/cert errors, TypeError: fetch failed from undici for an unreachable host, or any other transport exception resilientFetch treats as terminal.","commonSituations":"GITNEXUS_EMBEDDING_URL host does not resolve (typo, VPN down). Firewall blocking the endpoint. Self-signed or expired TLS cert. Port closed. Transient DNS hiccup that resilientFetch's retryable predicate did not catch.","solutions":["Read the sanitized reason in the message — it names the transport fault (e.g. ENOTFOUND, ECONNREFUSED) without leaking credentials.","Confirm reachability: `curl -v \"$GITNEXUS_EMBEDDING_URL/embeddings\"` from the indexer host.","Fix DNS/network: correct the URL host, bring up the VPN, open the firewall, or renew the TLS cert.","If the host uses credentials in the URL (user:pass@), note that safeUrl masks them but the underlying fetch may still reject credential-bearing URLs — move auth to GITNEXUS_EMBEDDING_API_KEY."],"exampleFix":"// before\nexport GITNEXUS_EMBEDDING_URL=https://embed-prod.internal     # DNS fails\n\n// after\nexport GITNEXUS_EMBEDDING_URL=https://embed.internal.example.com   # resolvable host","handlingStrategy":"try-catch","validationCode":"// Confirm the host resolves and is reachable before the run:\nconst u = new URL(process.env.GITNEXUS_EMBEDDING_URL!);\nawait import('node:dns').then(dns =>\n  dns.promises.lookup(u.hostname).catch(() => {\n    throw new Error(`${u.hostname} does not resolve; check GITNEXUS_EMBEDDING_URL`);\n  }),\n);","typeGuard":"import { isHttpEmbeddingError } from 'gitnexus';\nconst isTransportFailure = (e: unknown): boolean =>\n  isHttpEmbeddingError(e) &&\n  e instanceof Error &&\n  e.message.startsWith('Embedding request failed');","tryCatchPattern":"try {\n  await httpEmbed(texts);\n} catch (e) {\n  if (isTransportFailure(e)) {\n    // message reason is sanitized (URL creds + api key stripped);\n    // use it to diagnose DNS/firewall/TLS\n  }\n  throw e;\n}","preventionTips":["Put auth in GITNEXUS_EMBEDDING_API_KEY, not in the URL userinfo, to avoid undici credential-URL rejection and to keep logs clean.","Verify DNS + firewall reachability from the indexer host before a run.","Validate the URL parses (new URL(...)) at startup."],"tags":["network","transport","dns","tls","embeddings"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}