{"record":{"id":"ed7b0dda4edc4e2c","repo":"decolua/9router","slug":"extras-status-failed","errorCode":null,"errorMessage":"extras status failed","messagePattern":"extras status failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/app/(dashboard)/dashboard/token-saver/TokenSaverClient.js","lineNumber":149,"sourceCode":"        headers: { \"Cache-Control\": \"no-store\" },\n      });\n      const data = await res.json();\n      setHeadroomStatus({ ...data, loading: false });\n      if (!data?.installed) {\n        setHeadroomExtras({\n          version: null,\n          extras: { code: false, ml: false },\n          available: [\"code\", \"ml\"],\n          loading: false,\n        });\n        setPendingExtras([]);\n        return;\n      }\n      try {\n        const er = await fetch(\"/api/headroom/extras\", {\n          headers: { \"Cache-Control\": \"no-store\" },\n        });\n        if (!er.ok) throw new Error(\"extras status failed\");\n        const ed = await er.json();\n        setHeadroomExtras((s) => ({\n          ...s,\n          version: ed.version ?? null,\n          extras: ed.extras || { code: false, ml: false },\n          available: ed.available || [\"code\", \"ml\"],\n          loading: false,\n        }));\n        setPendingExtras([]);\n      } catch {\n        setHeadroomExtras({\n          version: null,\n          extras: { code: false, ml: false },\n          available: [\"code\", \"ml\"],\n          loading: false,\n        });\n        setPendingExtras([]);\n      }","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/app/(dashboard)/dashboard/token-saver/TokenSaverClient.js#L131-L167","documentation":"TokenSaverClient's headroom status refresh throws this when GET /api/headroom/extras returns a non-OK response. It reports that the extras status (code/ml availability and version) could not be fetched; the thrown message is caught locally and shown via headroom state rather than crashing the page.","triggerScenarios":"GET /api/headroom/extras (with Cache-Control: no-store) returns 4xx/5xx: headroom extras backend not installed/running, endpoint removed or moved in a version change, or auth failure on the dashboard API.","commonSituations":"Extras module never installed so its status route errors; server running an older build without the /api/headroom/extras route; proxy/port misconfiguration making the dashboard API unreachable; transient server restart during polling.","solutions":["Check the response status/body of /api/headroom/extras in the network tab","Install the headroom extras (use the card's install action → POST /api/headroom/extras) and retry","Verify the server build includes the extras status route (version match between UI and server)","Retry after confirming the gateway server is up and reachable"],"exampleFix":"// before\nif (!er.ok) throw new Error(\"extras status failed\");\n// after\nif (!er.ok) throw new Error(`extras status failed (HTTP ${er.status})`);","handlingStrategy":"try-catch","validationCode":"// probe endpoint health before relying on status\nconst er = await fetch(\"/api/headroom/extras\", { headers: { \"Cache-Control\": \"no-store\" } }).catch(() => null);\nif (!er || !er.ok) setHeadroomExtras(s => ({ ...s, available: [], extras: { code: false, ml: false } }));","typeGuard":null,"tryCatchPattern":"try {\n  const er = await fetch(\"/api/headroom/extras\");\n  if (!er.ok) throw new Error(`extras status failed (HTTP ${er.status})`);\n  const ed = await er.json();\n  setHeadroomExtras(s => ({ ...s, ...ed }));\n} catch (e) {\n  setHeadroomExtras(s => ({ ...s, available: [], extras: { code: false, ml: false } }));\n}","preventionTips":["Treat extras status as optional — degrade gracefully when the endpoint is down","Install extras before relying on code/ml availability flags","Keep server build in sync with the dashboard UI","Avoid hammering the endpoint in a polling loop during outages"],"tags":["http","status-check","dashboard","headroom"],"backgroundTag":"http-request-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}