{"record":{"id":"64b615ccdd873e2e","repo":"srbhr/Resume-Matcher","slug":"failed-to-load-prompt-config-status-res-status","errorCode":null,"errorMessage":"Failed to load prompt config (status ${res.status}).","messagePattern":"Failed to load prompt config \\(status (.+?)\\)\\.","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/config.ts","lineNumber":311,"sourceCode":"  label: string;\n  description: string;\n}\n\nexport interface PromptConfig {\n  default_prompt_id: string;\n  prompt_options: PromptOption[];\n}\n\nexport interface PromptConfigUpdate {\n  default_prompt_id?: string;\n}\n\n// Fetch prompt configuration\nexport async function fetchPromptConfig(): Promise<PromptConfig> {\n  const res = await apiFetch('/config/prompts', { credentials: 'include' });\n\n  if (!res.ok) {\n    throw new Error(`Failed to load prompt config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\n// Update prompt configuration\nexport async function updatePromptConfig(update: PromptConfigUpdate): Promise<PromptConfig> {\n  const res = await apiFetch('/config/prompts', {\n    method: 'PUT',\n    headers: { 'Content-Type': 'application/json' },\n    credentials: 'include',\n    body: JSON.stringify(update),\n  });\n\n  if (!res.ok) {\n    const data = await res.json().catch(() => ({}));\n    throw new Error(data.detail || `Failed to update prompt config (status ${res.status}).`);\n  }","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/config.ts#L293-L329","documentation":"fetchPromptConfig calls GET /config/prompts via apiFetch and throws this Error when the response is not ok (res.ok is false). It is the library's way of surfacing any non-2xx HTTP status from the backend prompt-config endpoint, including the status code in the message. The backend itself decided the request failed (auth, crash, missing endpoint) — this throw only reports it.","triggerScenarios":"Any GET /config/prompts response with a non-2xx status: 401/403 when the session cookie is missing/expired or CSRF fails, 404 when the backend route is absent or the Next.js proxy rewrite to BACKEND_ORIGIN is misconfigured, 500/502/503 when the backend is down or the prompt-config store fails to load, or a 404 from a stale NEXT_PUBLIC_API_URL/BACKEND_ORIGIN pointing at the wrong service.","commonSituations":"Backend not running on :8000 while frontend dev server proxies /api to it; user session expired so the cookie-authenticated config call 401s; deploying frontend without BACKEND_ORIGIN set so rewrites 502; upgrading the backend and /config/prompts was renamed or removed.","solutions":["Check the status code in the message: 401/403 → re-authenticate (log in again so credentials cookie is set); 404 → verify backend exposes /api/v1/config/prompts and next.config.ts rewrites target the right BACKEND_ORIGIN; 500/502/503 → check backend logs / whether the server on :8000 is up.","Confirm NEXT_PUBLIC_API_URL and BACKEND_ORIGIN env vars match your deployment (default '/' proxied to 127.0.0.1:8000 in dev).","Curl the endpoint directly (curl -i http://127.0.0.1:8000/api/v1/config/prompts with the session cookie) to isolate frontend proxy vs backend fault.","Add retry/fallback rendering in the calling UI so a transient 502 does not break the settings page."],"exampleFix":"// before\nconst res = await apiFetch('/config/prompts', { credentials: 'include' });\nif (!res.ok) {\n  throw new Error(`Failed to load prompt config (status ${res.status}).`);\n}\n\n// after\nconst res = await apiFetch('/config/prompts', { credentials: 'include' });\nif (res.status === 401) {\n  await refreshSession(); // re-login then retry once\n}\nif (!res.ok) {\n  throw new Error(`Failed to load prompt config (status ${res.status}).`);\n}","handlingStrategy":"try-catch","validationCode":"// Ensure session exists before calling authenticated config endpoints\nconst hasSession = document.cookie.includes('session');\nif (!hasSession) await ensureLogin();","typeGuard":"function isPromptConfig(x: unknown): x is PromptConfig {\n  return typeof x === 'object' && x !== null && 'prompts' in x;\n}","tryCatchPattern":"try {\n  const cfg = await fetchPromptConfig();\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.includes('status 401')) await reLoginAndRetry();\n  else showConfigError(msg);\n}","preventionTips":["Keep the backend on :8000 running before loading settings pages in dev","Verify NEXT_PUBLIC_API_URL / BACKEND_ORIGIN per environment","Monitor session expiry and refresh credentials before authenticated calls","Add fallback/placeholder rendering when config fetch fails"],"tags":["network","http","frontend-api-client","config"],"backgroundTag":"http-non-2xx-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}