abhigyanpatwari/GitNexus · error · HttpEmbeddingError

Embedding endpoint returned ${err.response.status} (${safeUr

Error message

Embedding endpoint returned ${err.response.status} (${safeUrl(url)}, batch ${batchIndex})

What it means

An HttpEmbeddingError thrown from httpEmbedBatch's catch block when resilientFetch raises ResilientFetchExhaustedError — every retry attempt received a non-OK HTTP status that resilientFetch retries (5xx and 429), and none recovered. The message reports the final response status (err.response.status). This is the exhausted form of a server-side or rate-limit status, distinct from error 132 which is a terminal 4xx returned without retry.

Source

Thrown at gitnexus/src/core/embeddings/http-client.ts:519

    // 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 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);
    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})`,

View on GitHub (pinned to d540b00184)

Solutions

  1. Check the reported status: 429 → reduce request frequency (raise GITNEXUS_EMBEDDING_MIN_INTERVAL_MS) or request a higher provider rate limit; 5xx → check provider status page and retry later.
  2. Increase the retry budget: GITNEXUS_EMBEDDING_MAX_ATTEMPTS (max 20) and GITNEXUS_EMBEDDING_RETRY_CAP_MS (max 300000ms) so transient outages are absorbed.
  3. Honor provider rate limits by spacing out indexing runs.
  4. Verify auth/model are correct (some providers return 500/503 for unknown models).

Example fix

// before
# default retry budget exhausted against a flapping endpoint

// after
export GITNEXUS_EMBEDDING_MAX_ATTEMPTS=5
export GITNEXUS_EMBEDDING_RETRY_CAP_MS=30000
export GITNEXUS_EMBEDDING_MIN_INTERVAL_MS=500
Defensive patterns

Strategy: retry

Validate before calling

// Cannot prevent a provider 5xx/429 from the caller; probe to detect early:
const r = await fetch(`${URL}/embeddings`, { /* ... */ });
if (r.status >= 500 || r.status === 429) {
  throw new Error(`Endpoint unhealthy (HTTP ${r.status}); fix before indexing`);
}

Type guard

import { isHttpEmbeddingError } from 'gitnexus';
const isExhaustedStatus = (e: unknown): boolean =>
  isHttpEmbeddingError(e) &&
  e instanceof Error &&
  /^Embedding endpoint returned \d{3} /.test(e.message);

Try / catch

// The library already retried; surface to the operator rather than re-looping.
try {
  await httpEmbed(texts);
} catch (e) {
  if (isExhaustedStatus(e)) {
    // provider is returning 5xx/429 persistently; back off the whole run
  }
  throw e;
}

Prevention

When it happens

Trigger: httpEmbedBatch after resilientFetch exhausts maxAttempts against a 5xx/429-returning endpoint. E.g. provider returning 503/502/500 on every attempt, or 429 with Retry-After that never lets up within the attempt budget. err.response.status carries the last status seen.

Common situations: Provider outage (5xx). Provider rate-limiting (429) that the backoff could not dodge because the sustained rate is too high. Model overloaded. Maintenance window returning 503. Bad gateway between you and the provider.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/008c09834c19d9f1. Report an issue: GitHub.