abhigyanpatwari/GitNexus · error · Error

LLM API error ( )

Error message

LLM API error (${response.status}): ${errorText.slice(0, 500)}

What it means

The endpoint returned a non-OK status that resilientFetch does not retry — a terminal 4xx (5xx/429 were already retried and would have surfaced as the 'after retries' error). The message includes the status code and first 500 chars of the response body. Common statuses: 401/403 (bad key), 404 (wrong base URL path or model), 400 (bad request payload/model name).

Solutions

  1. Read the status + body text: 401/403 → re-authenticate (`gitnexus wiki --api-key ...`), 404 → fix `--base-url` path (usually ends in /v1), 400 → check `--model` spelling
  2. Verify the endpoint manually: curl -H "Authorization: Bearer $KEY" $BASE_URL/chat/completions with a minimal payload
  3. For Azure, confirm the deployment name (`--model`) and URL shape https://{resource}.openai.azure.com/openai/v1
  4. Ensure the key has credit/quota and the model is enabled for the account

Example fix

# before (404 — missing /v1)
gitnexus wiki --provider custom --base-url https://api.example.com --model gpt-4o-mini

# after
gitnexus wiki --provider custom --base-url https://api.example.com/v1 --model gpt-4o-mini
Defensive patterns

Strategy: try-catch

Validate before calling

// Smoke-test credentials and endpoint shape before a long wiki run:
const probe = await fetch(`${baseUrl}/chat/completions`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ model, messages: [{ role: 'user', content: 'ping' }], max_tokens: 1 }),
});
if (probe.status === 401 || probe.status === 403 || probe.status === 404) {
  throw new Error(`LLM config invalid: ${probe.status} — fix --base-url/--api-key/--model before generating`);
}

Try / catch

try {
  await callLLM(prompt, config);
} catch (err) {
  const m = err instanceof Error ? err.message : '';
  if (/LLM API error \((401|403)\)/.test(m)) throw new Error('Re-authenticate: run gitnexus wiki --api-key <key>');
  if (/LLM API error \(404\)/.test(m)) throw new Error('Check --base-url (append /v1) and --model name');
  throw err;
}

Prevention

When it happens

Trigger: Invalid or revoked `--api-key` (401); missing entitlements for the model (403); `--base-url` pointing to a path that is not an OpenAI-compatible chat-completions endpoint (404); unknown `--model` name (400/404); Azure deployment name mismatch.

Common situations: Expired API key in ~/.gitnexus/config.json; wrong model identifier after a provider renamed models; base URL missing or adding /v1; Azure deployment vs model-name confusion; corporate proxy returning 403.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20). Data as JSON: /api/errors/8a1335ea75e00bb1. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/core/wiki/llm-client.ts:448

  }

  if (!response.ok) {
    const errorText = await response.text().catch(() => 'unknown error');

    // Azure content filter — surface a clear message instead of a generic API error.
    if (
      azure &&
      response.status === 400 &&
      (errorText.includes('content_filter') || errorText.includes('ResponsibleAIPolicyViolation'))
    ) {
      throw new Error(
        `Azure content filter blocked this request. The prompt triggered content policy. Details: ${errorText.slice(0, 300)}`,
      );
    }

    // Any other non-OK response here is a terminal 4xx — resilientFetch
    // already retried 5xx/429 to exhaustion and would have thrown above.
    throw new Error(`LLM API error (${response.status}): ${errorText.slice(0, 500)}`);
  }

  // Streaming path
  if (useStream && response.body) {
    return await readSSEStream(response.body, options!.onChunk!);
  }

  // Non-streaming path
  const json = (await response.json()) as any;
  const choice = json.choices?.[0];
  if (!choice?.message?.content) {
    throw new Error('LLM returned empty response');
  }

  return {
    content: choice.message.content,
    promptTokens: json.usage?.prompt_tokens,
    completionTokens: json.usage?.completion_tokens,

View on GitHub (pinned to 52924ef12c)