abhigyanpatwari/GitNexus · error · HttpEmbeddingError

Embedding endpoint returned ${resp.status} (${safeUrl(url)},

Error message

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

What it means

An HttpEmbeddingError thrown after the retry loop when resilientFetch returns a non-OK response. Per the inline comment, resilientFetch already retried 5xx and 429, so any non-OK response reaching this point is a terminal client error — a 4xx other than 429. The message reports resp.status. These are not retried because retrying a 401/403/400/404 cannot change the outcome.

Source

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

    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.
    throw new HttpEmbeddingError(unparseableMessage());
  }
  return parsed;
};

/**
 * Embed texts via the HTTP backend, splitting into batches.
 * Reads config from env vars on every call.
 *

View on GitHub (pinned to d540b00184)

Solutions

  1. Match the fix to the status: 401/403 → set a valid GITNEXUS_EMBEDDING_API_KEY; 400/404 → fix GITNEXUS_EMBEDDING_MODEL and GITNEXUS_EMBEDDING_URL; 422/400 on a strict backend → set GITNEXUS_EMBEDDING_REQUEST_DIMS=omit.
  2. Reproduce with curl to see the provider's error body: `curl -i -X POST "$URL/embeddings" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"model":"'$MODEL'","input":"x"}'`.
  3. For 413, reduce input size; for 429 see error 130 (rate-limited, retried).

Example fix

// before: strict backend rejects the `dimensions` request field
export GITNEXUS_EMBEDDING_DIMS=1536
export GITNEXUS_EMBEDDING_REQUEST_DIMS=1536

// after: declare expected width, suppress the request hint
export GITNEXUS_EMBEDDING_DIMS=1536
export GITNEXUS_EMBEDDING_REQUEST_DIMS=omit
Defensive patterns

Strategy: validation

Validate before calling

// Probe and reject known-bad configurations before indexing:
const r = await fetch(`${URL}/embeddings`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${KEY}` }, body: JSON.stringify({ model: MODEL, input: 'x' }) });
if (r.status === 401 || r.status === 403) throw new Error('Bad API key');
if (r.status === 404) throw new Error('Wrong URL or model');
if (r.status >= 400 && r.status !== 429) throw new Error(`Endpoint rejected probe: ${r.status}`);

Type guard

import { isHttpEmbeddingError } from 'gitnexus';
const isTerminalStatus = (e: unknown): boolean =>
  isHttpEmbeddingError(e) &&
  e instanceof Error &&
  /^Embedding endpoint returned (4\d{2}|[45]\d{2}) /.test(e.message);

Try / catch

try {
  await httpEmbed(texts);
} catch (e) {
  if (isHttpEmbeddingError(e)) {
    const m = /returned (\d{3}) /.exec(e.message);
    if (m && m[1] !== '429') {
      // terminal 4xx: fix auth/model/URL; do not retry
    }
  }
  throw e;
}

Prevention

When it happens

Trigger: httpEmbedBatch after resilientFetch returns a 4xx (non-429) response. Common: 401/403 (bad or missing GITNEXUS_EMBEDDING_API_KEY), 400 (malformed request body, unknown model, or the `dimensions` field rejected by a strict backend), 404 (wrong baseUrl path), 413 (batch body too large), 422 (unprocessable input).

Common situations: Missing/expired/typo'd API key (401/403). GITNEXUS_EMBEDDING_MODEL not available on the endpoint (400/404). baseUrl with a wrong path (404). A strict backend rejecting the `dimensions` request field — fix by setting GITNEXUS_EMBEDDING_REQUEST_DIMS=omit while keeping GITNEXUS_EMBEDDING_DIMS at the output width. Inputs exceeding the provider's content limit (413).

Related errors


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