srbhr/Resume-Matcher · error · Error

Failed to load LLM config (status ${res.status}).

Error message

Failed to load LLM config (status ${res.status}).

What it means

fetchLlmConfig calls GET /config/llm-api-key with credentials and throws this Error when the response is not ok. It intentionally discards the response body, so only the HTTP status is available for diagnosis.

Source

Thrown at apps/frontend/lib/api/config.ts:71

  provider: string;
  model: string;
  error?: string;
  error_code?: string;
  response_model?: string;
  warning?: string;
  warning_code?: string;
  test_prompt?: string;
  model_output?: string;
  reasoning_content?: string | null;
  error_detail?: string;
}

// Fetch full LLM configuration
export async function fetchLlmConfig(): Promise<LLMConfig> {
  const res = await apiFetch('/config/llm-api-key', { credentials: 'include' });

  if (!res.ok) {
    throw new Error(`Failed to load LLM config (status ${res.status}).`);
  }

  return res.json();
}

// Legacy function for backwards compatibility
export async function fetchLlmApiKey(): Promise<string> {
  const config = await fetchLlmConfig();
  return config.api_key ?? '';
}

// Update LLM configuration
export async function updateLlmConfig(config: LLMConfigUpdate): Promise<LLMConfig> {
  const res = await apiFetch('/config/llm-api-key', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify(config),

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Check the reported status: log in again if 401/403 (credentials: 'include' requires a valid session cookie)
  2. Confirm the backend is running a version that exposes GET /config/llm-api-key (404 means route mismatch or wrong base URL)
  3. Check backend logs for a 500 cause (config storage/migration error)
  4. Verify the frontend API base URL points at the correct backend

Example fix

// before
const cfg = await fetchLlmConfig();
// after
let cfg;
try {
  cfg = await fetchLlmConfig();
} catch (e) {
  if (e.message.includes('status 401')) redirect('/login');
  else cfg = DEFAULT_LLM_CONFIG;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure a session exists before fetching config
const sessionOk = document.cookie.includes('session');
if (!sessionOk) await ensureLogin();

Type guard

function isConfigLoadError(e: unknown): e is Error & { status?: number } {
  const m = e instanceof Error ? e.message.match(/status (\d{3})/) : null;
  if (e instanceof Error && m) (e as any).status = Number(m[1]);
  return e instanceof Error;
}

Try / catch

try {
  cfg = await fetchLlmConfig();
} catch (e) {
  if (isConfigLoadError(e) && (e as any).status === 401) redirect('/login');
  else cfg = DEFAULT_LLM_CONFIG;
}

Prevention

When it happens

Trigger: GET /config/llm-api-key returns non-OK: 401 (no/invalid session cookie), 404 (backend version without that route), 500 (backend config store failure).

Common situations: Opening the settings page before logging in; backend deployed at an older version missing the /config/llm-api-key endpoint; backend database/migration failure on startup.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/4a7ff5e0ccd0a34f. Report an issue: GitHub.