{"record":{"id":"062f6f826c4c8189","repo":"affaan-m/ECC","slug":"control-plane-request-failed","errorCode":null,"errorMessage":"Control-plane request failed","messagePattern":"Control-plane request failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/control-pane/control-plane-view-ui.js","lineNumber":227,"sourceCode":"  function apply(data) {\n    if (!data || data.schemaVersion !== 'ecc.control-plane.view.v1' ||\n        !['tasks', 'lanes', 'pairs', 'events'].every(function (key) { return Array.isArray(data[key]); }) ||\n        !data.projection || !Array.isArray(data.projection.agents) || !data.thresholds ||\n        !Number.isFinite(data.thresholds.ta) || !Number.isFinite(data.thresholds.ra)) {\n      throw new Error('Invalid control-plane view');\n    }\n    view = Object.assign({}, data);\n    renderEvents(); renderLanes(); draw();\n    var c = view.counts || {};\n    document.getElementById('status').textContent =\n      (c.tasks || 0) + ' tasks in ' + (c.lanes || 0) + ' lanes | ' + (c.agents || 0) + ' with edits | ' +\n      (c.advisories || 0) + ' advisories (' + (c.resolutions || 0) + ' steering)' +\n      (view.inventory && view.inventory.status !== 'ok' ? ' | inventory ' + view.inventory.status : '');\n  }\n\n  function poll() {\n    fetch('/api/control-plane').then(function (r) {\n      if (!r.ok) throw new Error('Control-plane request failed');\n      return r.json();\n    }).then(apply).catch(function () {\n      document.getElementById('status').textContent = 'offline';\n    });\n  }\n\n  resize();\n  poll();\n  setInterval(poll, 5000);\n})();\n</script>\n</body>\n</html>`;\n}\n\nmodule.exports = { renderControlPlaneViewHtml };\n","sourceCodeStart":209,"sourceCodeEnd":244,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/control-pane/control-plane-view-ui.js#L209-L244","documentation":"The control-plane view polls /api/control-plane and throws 'Control-plane request failed' whenever the fetch resolves but the HTTP response is not ok (non-2xx). The poll's catch handler then sets the status display to 'offline', so users see the dashboard go offline while the server is erroring.","triggerScenarios":"fetch('/api/control-plane') returns r.ok === false — e.g. 500 from a server-side snapshot failure, 404 after the route was moved, or 502/503 from a proxy while the control-plane server restarts.","commonSituations":"Control-plane server crashed or is restarting; wrong port/host so requests hit another service; API route renamed in an upgrade; proxy (nginx/traefik) returning 502 when the upstream is down.","solutions":["Check the control-plane server logs for the error behind the non-2xx response","Verify the page is served from the same server that exposes /api/control-plane (correct --host/--port)","Curl /api/control-plane directly and inspect the status code and body","Restart the control-plane server or fix the failing snapshot endpoint"],"exampleFix":"// before\nfetch('/api/control-plane').then(r => { if (!r.ok) throw new Error('Control-plane request failed'); ... });\n// after\nfetch('/api/control-plane').then(r => {\n  if (!r.ok) throw new Error(`Control-plane request failed: HTTP ${r.status}`);\n  return r.json();\n}).then(apply).catch(err => { setStatus('offline'); console.warn(err.message); });","handlingStrategy":"try-catch","validationCode":"const res = await fetch('/api/control-plane');\nif (!res.ok) console.warn('control-plane HTTP', res.status); // decide before calling apply","typeGuard":"const isHealthy = (r) => r.ok;","tryCatchPattern":"fetch('/api/control-plane')\n  .then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })\n  .then(apply)\n  .catch(err => { setStatus('offline'); console.warn('control-plane unreachable:', err.message); });","preventionTips":["Monitor the control-plane server process health","Serve the UI and API from the same host/port","Check proxy (nginx/traefik) upstream configs","Add alerting on repeated non-2xx /api/control-plane responses"],"tags":["http","network","polling"],"backgroundTag":"http-error-response","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}