{"record":{"id":"9b0d956da40ab945","repo":"paperclipai/paperclip","slug":"http-status","errorCode":null,"errorMessage":"HTTP ${status}","messagePattern":"HTTP \\$\\{status\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/kv-demo-mcp-server/src/render.ts","lineNumber":101,"sourceCode":"      const rows = document.getElementById(\"rows\");\n      if (!state.entries.length) {\n        rows.innerHTML = '<tr class=\"empty\"><td colspan=\"3\">No values yet — call the <code>kv_set</code> tool to add one.</td></tr>';\n        return;\n      }\n      rows.innerHTML = state.entries.map((entry) =>\n        '<tr><td class=\"key\">' + escapeHtml(entry.key) +\n        '</td><td class=\"value\">' + escapeHtml(entry.value) +\n        '</td><td class=\"updated\">' + escapeHtml(entry.updatedAt) + '</td></tr>'\n      ).join(\"\");\n    }\n    async function refresh() {\n      const status = document.getElementById(\"status\");\n      try {\n        const headers = { accept: \"application/json\" };\n        if (token) headers.authorization = \"Bearer \" + token;\n        if (TOKEN_REQUIRED && !token) throw new Error(\"Add #token=YOUR_TOKEN to this URL\");\n        const res = await fetch(\"/api/state\", { headers });\n        if (!res.ok) throw new Error(\"HTTP \" + res.status);\n        render(await res.json());\n        status.textContent = \"Auto-refreshing every 2s.\";\n      } catch (err) {\n        status.textContent = \"Refresh failed: \" + err.message;\n      }\n    }\n    setInterval(refresh, 2000);\n  </script>\n</body>\n</html>`;\n}\n","sourceCodeStart":83,"sourceCodeEnd":113,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/kv-demo-mcp-server/src/render.ts#L83-L113","documentation":"Also from the dashboard's refresh() in the rendered HTML: after fetch('/api/state') it checks res.ok and throws 'HTTP <status>' otherwise. The thrown value is caught and shown as 'Refresh failed: HTTP <code>'. This is the generic non-OK response path; 401 (bad/missing token) and 500 are the common causes.","triggerScenarios":"The /api/state request returns a non-2xx status — most often 401 when the token in the URL hash is wrong/expired, or 500 from a server-side store error.","commonSituations":"Wrong token in the fragment; token auth enabled server-side and the request was sent without/with-stale Authorization header; server crash or store corruption returning 500.","solutions":["If status is 401, correct the #token= fragment (see error 446).","If status is 500, inspect the server logs for the underlying store error.","Confirm the dashboard URL host/port still match the running server."],"exampleFix":"// status element shows: Refresh failed: HTTP 401\n// fix: update URL fragment\nhttps://host:8848/#token=<correct-token>","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { const r = await fetch('/api/state', { headers }); if (!r.ok) throw new Error('HTTP '+r.status); ... }\ncatch (e) {\n  if (/HTTP 401/.test(e.message)) { /* fix token */ } else if (/HTTP 5\\d\\d/.test(e.message)) { /* surface server error */ } else throw e;\n}","preventionTips":["On 401, verify the #token= fragment matches the server-configured token.","On 5xx, check server logs before retrying.","Do not retry blindly on 4xx — the request is malformed/forbidden."],"tags":["http","client-side","auth","kv-demo-mcp"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}