{"record":{"id":"b70a9c1ca72a3efb","repo":"srbhr/Resume-Matcher","slug":"data-detail-failed-to-update-feature-config","errorCode":null,"errorMessage":"${data.detail || Failed to update feature config (status ${res.status}).}","messagePattern":"\\$\\{data\\.detail \\|\\| Failed to update feature config \\(status \\$\\{res\\.status\\}\\)\\.\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/config.ts","lineNumber":243,"sourceCode":"  if (!res.ok) {\n    throw new Error(`Failed to load feature config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\n// Update feature configuration\nexport async function updateFeatureConfig(config: FeatureConfigUpdate): Promise<FeatureConfig> {\n  const res = await apiFetch('/config/features', {\n    method: 'PUT',\n    headers: { 'Content-Type': 'application/json' },\n    credentials: 'include',\n    body: JSON.stringify(config),\n  });\n\n  if (!res.ok) {\n    const data = await res.json().catch(() => ({}));\n    throw new Error(data.detail || `Failed to update feature config (status ${res.status}).`);\n  }\n\n  return res.json();\n}\n\n// Language configuration types\nexport type SupportedLanguage = 'en' | 'es' | 'zh' | 'ja' | 'pt' | 'fr' | 'ko';\n\nexport interface LanguageConfig {\n  ui_language: SupportedLanguage;\n  content_language: SupportedLanguage;\n  supported_languages: SupportedLanguage[];\n}\n\nexport interface LanguageConfigUpdate {\n  ui_language?: SupportedLanguage;\n  content_language?: SupportedLanguage;\n}","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/config.ts#L225-L261","documentation":"updateFeatureConfig PUTs the feature configuration to /config/features and throws an Error on non-OK responses, preferring the backend's JSON `detail` field (FastAPI validation message) and falling back to a generic status-message string when the body cannot be parsed.","triggerScenarios":"Saving feature toggles when the backend rejects them: 422 schema validation (unknown/missing feature keys or wrong types after a frontend/backend version skew), 401 session expired, 500 persistence failure.","commonSituations":"Frontend and backend deployed at different versions so the feature-flag schema no longer matches; user's session expired while editing; concurrent config writes causing a backend conflict.","solutions":["Read the `detail` in the thrown message — it names the offending field/value; align the submitted FeatureConfig with the backend schema","Re-login if status is 401/403","Ensure frontend and backend versions match so the feature schema is identical","Check backend logs for 500 persistence errors"],"exampleFix":"// before\nawait updateFeatureConfig({ enableX: 'yes' }); // 422: enableX expected boolean\n// after\nawait updateFeatureConfig({ enableX: true });","handlingStrategy":"validation","validationCode":"function validateFeatureConfig(c: Record<string, unknown>, schema: Record<string, 'boolean' | 'string' | 'number'>): string | null {\n  for (const [k, t] of Object.entries(schema)) {\n    const v = c[k];\n    if (v === undefined) return `missing key: ${k}`;\n    if (t === 'boolean' && typeof v !== 'boolean') return `${k} must be boolean`;\n    if (t === 'number' && typeof v !== 'number') return `${k} must be number`;\n  }\n  return null;\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 updateFeatureConfig(config);\n} catch (e) {\n  showToast(e instanceof Error ? e.message : 'Feature config save failed'); // message carries backend detail\n}","preventionTips":["Generate the frontend FeatureConfig type from the backend schema","Block saves when a version-skew check (backend build id) mismatches","Validate all feature keys/types against the current schema before PUT","Refresh auth tokens before mutations after idle periods"],"tags":["http","config","validation","frontend"],"backgroundTag":"http-error-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}