abhigyanpatwari/GitNexus · error · HttpEmbeddingError
Embedding endpoint circuit open
Error message
Embedding endpoint circuit open (${safeUrl(url)}, batch ${batchIndex}): retry in ${Math.ceil(err.retryAfterMs / 1000)}s What it means
httpEmbedBatch maps CircuitOpenError from resilientFetch to this message: the process-global 'embeddings-http' circuit breaker (shared across all batches) opened after repeated endpoint failures, and the breaker is refusing new attempts until its cooldown elapses (retry-after shown in seconds). Failing fast protects the endpoint and avoids multi-second hangs per batch.
Solutions
- Wait the stated retry window before issuing further embedding calls.
- Fix the endpoint (see accompanying failures in logs — status codes, timeouts) so the breaker closes on success.
- Scale or stabilize the endpoint if it trips the breaker under batch load; lower batch rate with GITNEXUS_EMBEDDING_MIN_INTERVAL_MS.
- Restart the process to reset the in-memory breaker after the endpoint is healthy (state is per-process).
Defensive patterns
Strategy: retry
Validate before calling
// breaker state is internal; pace requests to keep it closed process.env.GITNEXUS_EMBEDDING_MIN_INTERVAL_MS = '250'; // pacing floor before big runs
Type guard
const isEndpointCircuitOpen = (e: unknown): boolean =>
e instanceof Error && e.message.includes('Embedding endpoint circuit open'); Try / catch
try {
vectors = await httpEmbed(texts);
} catch (e) {
if (isEndpointCircuitOpen(e)) {
const secs = Number(/retry in (\d+)s/.exec(e.message)?.[1] ?? 60);
await new Promise((r) => setTimeout(r, (secs + 1) * 1000));
return httpEmbed(texts); // one bounded retry after cooldown
}
throw e;
} Prevention
- Stabilize/scale the endpoint before large embedding runs; the breaker is per-process and resets on restart.
- Add pacing (GITNEXUS_EMBEDDING_MIN_INTERVAL_MS) to avoid tripping it under load.
- Investigate the failures that opened it (5xx/network) rather than only honoring the cooldown.
When it happens
Trigger: Sustained endpoint failures (5xx storms, network errors, bad-body retries) earlier in the same process tripping the breaker; the next embed batch — or a new query in the same session — is then rejected immediately with the remaining cooldown.
Common situations: Endpoint outage or overload during a long analyze --embeddings run in HTTP mode; rerunning a query immediately after a cascade of failures.
Related errors
- : HuggingFace download circuit is open after repeated…
- : HuggingFace download circuit opened after consecutive…
- Embedding endpoint returned an unexpected response shape
- Embedding endpoint returned an unparseable response
- Embedding endpoint returned
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/efba77786b865365.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/embeddings/http-client.ts:562
throw new HttpEmbeddingError(
`Embedding request cancelled (${safeUrl(url)}, batch ${batchIndex})`,
{ cause: err },
);
}
// Retries are exhausted on a bad 2xx body. Surface the message the sentinel
// carried, keeping the underlying parse error in `cause` only — the body
// text must never reach the `sanitizeReason` fallback and leak to stderr.
if (err instanceof RetryableEmbeddingBodyError) {
throw new HttpEmbeddingError(err.terminalMessage, { cause: err.cause });
}
if (err instanceof RetryableEmbeddingTimeoutError) {
throw new HttpEmbeddingError(
`${err.message} after ${maxAttempts} attempt(s) (${safeUrl(url)}, batch ${batchIndex})`,
{ cause: err.cause },
);
}
if (err instanceof CircuitOpenError) {
throw new HttpEmbeddingError(
`Embedding endpoint circuit open (${safeUrl(url)}, batch ${batchIndex}): retry in ${Math.ceil(err.retryAfterMs / 1000)}s`,
{ 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);View on GitHub (pinned to ac9a4e9abd)