{"record":{"id":"f688ba961b19cc1e","repo":"srbhr/Resume-Matcher","slug":"data-detail-failed-to-update-language-config","errorCode":null,"errorMessage":"${data.detail || Failed to update language config (status ${res.status}).}","messagePattern":"\\$\\{data\\.detail \\|\\| Failed to update language config \\(status \\$\\{res\\.status\\}\\)\\.\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/config.ts","lineNumber":285,"sourceCode":"  if (!res.ok) {\n    throw new Error(`Failed to load language config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\n// Update language configuration\nexport async function updateLanguageConfig(update: LanguageConfigUpdate): Promise<LanguageConfig> {\n  const res = await apiFetch('/config/language', {\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 language config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\nexport interface PromptOption {\n  id: string;\n  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;","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/config.ts#L267-L303","documentation":"updateLanguageConfig PUTs the language update to /config/language and throws an Error on non-OK responses, using the backend JSON `detail` field when present (FastAPI error payloads) and otherwise a generic status-message fallback; body parse failures are swallowed with .catch(() => ({})).","triggerScenarios":"Saving a content language the backend rejects: 422 validation (unsupported language code), 401 session expired, 500 persistence failure.","commonSituations":"Submitting a language code not in the backend's supported list (e.g. after a locale rename); session expiring mid-edit; backend DB write failure.","solutions":["Use the `detail` in the thrown message to fix the submitted language code — it must match the backend's supported-language list","Re-login if status is 401/403","Validate the language code against the backend's supported list client-side before submitting","Check backend logs if the generic fallback message appears (500)"],"exampleFix":"// before\nawait updateLanguageConfig({ contentLanguage: 'jp' }); // 422 unsupported code\n// after\nawait updateLanguageConfig({ contentLanguage: 'ja' });","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['en','de','fr','es','ja','zh'];\nfunction validateLanguageUpdate(u: { contentLanguage: string }): string | null {\n  return SUPPORTED.includes(u.contentLanguage) ? null : `unsupported language: ${u.contentLanguage}`;\n}","typeGuard":"function hasDetail(x: unknown): x is { detail: string } {\n  return typeof x === 'object' && x !== null && 'detail' in x && typeof (x as any).detail === 'string';\n}","tryCatchPattern":"try {\n  await updateLanguageConfig(update);\n} catch (e) {\n  showToast(e instanceof Error ? e.message : 'Language update failed'); // may carry backend detail\n}","preventionTips":["Derive the language picker options from the backend's supported-language list","Normalize ISO codes (e.g. 'jp' -> 'ja') before submitting","Refresh the session before mutations after idle","Handle the thrown `detail` message in the UI instead of swallowing it"],"tags":["http","config","i18n","validation"],"backgroundTag":"http-error-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}