abhigyanpatwari/GitNexus · error · HttpEmbeddingError
Embedding request failed (${safeUrl(url)}, batch ${batchInde
Error message
Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason} What it means
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.
Source
Thrown at gitnexus/src/core/embeddings/http-client.ts:527
{ cause: err },
);
}
if (err instanceof DOMException && err.name === 'TimeoutError') {
throw new HttpEmbeddingError(
`Embedding request timed out after ${timeoutMs}ms (${safeUrl(url)}, batch ${batchIndex})`,
{ cause: err },
);
}
if (err instanceof ResilientFetchExhaustedError) {
throw new HttpEmbeddingError(
`Embedding endpoint returned ${err.response.status} (${safeUrl(url)}, batch ${batchIndex})`,
{ cause: err },
);
}
const reason = sanitizeReason(err instanceof Error ? err.message : String(err), url, apiKey);
const safeCause = new Error(reason);
safeCause.name = err instanceof Error ? err.name : 'EmbeddingTransportError';
throw new HttpEmbeddingError(
`Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason}`,
{ cause: safeCause },
);
}
if (!resp.ok) {
// resilientFetch already retried 5xx/429; any non-OK response here is
// a terminal client error (4xx other than 429).
throw new HttpEmbeddingError(
`Embedding endpoint returned ${resp.status} (${safeUrl(url)}, batch ${batchIndex})`,
);
}
if (parsed === undefined) {
// Defensively unreachable: an OK response either sets `parsed` or throws
// out of `fetchImpl`. Kept so the narrowing holds without a non-null
// assertion, and so a future `resilientFetch` change can't return an
// unvalidated body silently.View on GitHub (pinned to d540b00184)
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.
Example fix
// before export GITNEXUS_EMBEDDING_URL=https://embed-prod.internal # DNS fails // after export GITNEXUS_EMBEDDING_URL=https://embed.internal.example.com # resolvable host
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the host resolves and is reachable before the run:
const u = new URL(process.env.GITNEXUS_EMBEDDING_URL!);
await import('node:dns').then(dns =>
dns.promises.lookup(u.hostname).catch(() => {
throw new Error(`${u.hostname} does not resolve; check GITNEXUS_EMBEDDING_URL`);
}),
); Type guard
import { isHttpEmbeddingError } from 'gitnexus';
const isTransportFailure = (e: unknown): boolean =>
isHttpEmbeddingError(e) &&
e instanceof Error &&
e.message.startsWith('Embedding request failed'); Try / catch
try {
await httpEmbed(texts);
} catch (e) {
if (isTransportFailure(e)) {
// message reason is sanitized (URL creds + api key stripped);
// use it to diagnose DNS/firewall/TLS
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Local semantic embeddings are unavailable: the optional embe
- Failed to download embedding model: ${errMsg} ${endpointHi
- Embedding endpoint returned an unparseable response (${safeU
- Embedding endpoint circuit open (${safeUrl(url)}, batch ${ba
- Embedding request timed out after ${timeoutMs}ms (${safeUrl(
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/b750d553eaf69212.
Report an issue: GitHub.