{"record":{"id":"4a7ff5e0ccd0a34f","repo":"srbhr/Resume-Matcher","slug":"failed-to-load-llm-config-status-res-status","errorCode":null,"errorMessage":"Failed to load LLM config (status ${res.status}).","messagePattern":"Failed to load LLM config \\(status (.+?)\\)\\.","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/config.ts","lineNumber":71,"sourceCode":"  provider: string;\n  model: string;\n  error?: string;\n  error_code?: string;\n  response_model?: string;\n  warning?: string;\n  warning_code?: string;\n  test_prompt?: string;\n  model_output?: string;\n  reasoning_content?: string | null;\n  error_detail?: string;\n}\n\n// Fetch full LLM configuration\nexport async function fetchLlmConfig(): Promise<LLMConfig> {\n  const res = await apiFetch('/config/llm-api-key', { credentials: 'include' });\n\n  if (!res.ok) {\n    throw new Error(`Failed to load LLM config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\n// Legacy function for backwards compatibility\nexport async function fetchLlmApiKey(): Promise<string> {\n  const config = await fetchLlmConfig();\n  return config.api_key ?? '';\n}\n\n// Update LLM configuration\nexport async function updateLlmConfig(config: LLMConfigUpdate): Promise<LLMConfig> {\n  const res = await apiFetch('/config/llm-api-key', {\n    method: 'PUT',\n    headers: { 'Content-Type': 'application/json' },\n    credentials: 'include',\n    body: JSON.stringify(config),","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/config.ts#L53-L89","documentation":"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.","triggerScenarios":"GET /config/llm-api-key returns non-OK: 401 (no/invalid session cookie), 404 (backend version without that route), 500 (backend config store failure).","commonSituations":"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.","solutions":["Check the reported status: log in again if 401/403 (credentials: 'include' requires a valid session cookie)","Confirm the backend is running a version that exposes GET /config/llm-api-key (404 means route mismatch or wrong base URL)","Check backend logs for a 500 cause (config storage/migration error)","Verify the frontend API base URL points at the correct backend"],"exampleFix":"// before\nconst cfg = await fetchLlmConfig();\n// after\nlet cfg;\ntry {\n  cfg = await fetchLlmConfig();\n} catch (e) {\n  if (e.message.includes('status 401')) redirect('/login');\n  else cfg = DEFAULT_LLM_CONFIG;\n}","handlingStrategy":"try-catch","validationCode":"// Ensure a session exists before fetching config\nconst sessionOk = document.cookie.includes('session');\nif (!sessionOk) await ensureLogin();","typeGuard":"function isConfigLoadError(e: unknown): e is Error & { status?: number } {\n  const m = e instanceof Error ? e.message.match(/status (\\d{3})/) : null;\n  if (e instanceof Error && m) (e as any).status = Number(m[1]);\n  return e instanceof Error;\n}","tryCatchPattern":"try {\n  cfg = await fetchLlmConfig();\n} catch (e) {\n  if (isConfigLoadError(e) && (e as any).status === 401) redirect('/login');\n  else cfg = DEFAULT_LLM_CONFIG;\n}","preventionTips":["Gate settings pages behind an auth check","Keep frontend and backend versions in lockstep so routes exist","Provide default config fallbacks so the UI degrades gracefully","Curl /config/llm-api-key during deployment smoke tests"],"tags":["http","config","fetch","frontend"],"backgroundTag":"http-error-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}