abhigyanpatwari/GitNexus · error · Error

LLM endpoint circuit open: retry in

Error message

LLM endpoint circuit open: retry in ${Math.ceil(err.retryAfterMs / 1000)}s. ${err.message}

What it means

All LLM calls go through resilientFetch keyed by breakerKey `wiki-llm-<host>`. After repeated failures on that host the per-host circuit breaker opens and subsequent calls fail immediately with CircuitOpenError instead of hitting the endpoint; this error wraps it, telling you how long (retryAfterMs, shown in seconds) until the breaker half-opens. It means 'stop hammering, the endpoint is considered down', not that the latest single request failed.

Solutions

  1. Wait the indicated cooldown (retryAfterMs), then rerun — the breaker resets automatically
  2. Address the upstream cause: check API status, rate limits, and reduce `--concurrency` (default 3)
  3. If rate-limited, lower concurrency and/or request a higher rate limit or quota
  4. In a fresh process the breaker starts closed, so rerunning the CLI after fixing the endpoint works immediately

Example fix

# before
gitnexus wiki --concurrency 8   # trips breaker under 429s

# after
gitnexus wiki --concurrency 2   # retry after cooldown window
Defensive patterns

Strategy: retry

Try / catch

try {
  await callLLM(prompt, config);
} catch (err) {
  if (err instanceof Error && err.message.includes('circuit open: retry in')) {
    const waitMs = Number(err.message.match(/retry in (\d+)s/)?.[1] ?? 30) * 1000;
    await sleep(waitMs + 1000); // breaker half-opens; retry once
    return callLLM(prompt, config);
  }
  throw err;
}

Prevention

When it happens

Trigger: A run of wiki LLM calls to one API host fails repeatedly (5xx, 429, network errors) until the breaker trips; then the next callLLM invocation within the cooldown window throws this immediately. High `--concurrency` against a rate-limited or degraded endpoint trips it fastest.

Common situations: Rate limiting (429s) during a large wiki generation with parallel calls; an outage or degraded LLM gateway; on-prem proxy returning 502s; immediately rerunning after a failed run while the breaker (in-process) is still open in long-lived processes.

Related errors


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

Appendix: source

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

          ...authHeaders,
        },
        body: JSON.stringify(body),
        // Request timeout is opt-in for wiki generation. Large local
        // model runs can legitimately take well over a minute, so the
        // default runtime path must not impose a hidden 60s ceiling.
        signal:
          config.requestTimeoutMs !== undefined
            ? AbortSignal.timeout(config.requestTimeoutMs)
            : undefined,
      },
      {
        breakerKey: `wiki-llm-${new URL(url).host}`,
        retry: { maxAttempts: config.maxAttempts ?? 3, baseDelayMs: 2_000, capDelayMs: 30_000 },
      },
    );
  } catch (err) {
    if (err instanceof CircuitOpenError) {
      throw new Error(
        `LLM endpoint circuit open: retry in ${Math.ceil(err.retryAfterMs / 1000)}s. ${err.message}`,
      );
    }
    if (err instanceof ResilientFetchExhaustedError) {
      const errorText = await err.response.text().catch(() => 'unknown error');
      throw new Error(
        `LLM API error (${err.response.status} after retries): ${errorText.slice(0, 500)}`,
      );
    }
    if (config.requestTimeoutMs !== undefined && isTimeoutLikeError(err)) {
      throw new Error(
        `LLM request timed out after ${formatTimeoutDuration(config.requestTimeoutMs)}. ` +
          'Increase --timeout or omit it to disable the request timeout.',
      );
    }
    throw err;
  }

View on GitHub (pinned to 52924ef12c)