{"record":{"id":"99123425ee7c1e12","repo":"affaan-m/ECC","slug":"invalid-control-plane-view","errorCode":null,"errorMessage":"Invalid control-plane view","messagePattern":"Invalid control-plane view","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/control-pane/control-plane-view-ui.js","lineNumber":214,"sourceCode":"        var row = document.createElement('div'); row.className = 'task';\n        var idEl = document.createElement('span'); idEl.className = 'id'; idEl.textContent = t.id.slice(0, 20);\n        var st = document.createElement('span'); st.textContent = t.harness + ' / ' + t.state + ' / ' + (t.workingSet.fileCount || 0) + ' files';\n        var risk = document.createElement('span'); risk.className = 'risk';\n        risk.style.color = riskColor(t.projection.maxRisk || 0);\n        risk.textContent = t.projection.point ? Math.round((t.projection.maxRisk || 0) * 100) + '%' : 'no pair';\n        row.appendChild(idEl); row.appendChild(st); row.appendChild(risk);\n        el.appendChild(row);\n      });\n      box.appendChild(el);\n    });\n  }\n\n  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  }","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/control-pane/control-plane-view-ui.js#L196-L232","documentation":"The control-plane view UI validates every payload applied to the view: it must carry schemaVersion 'ecc.control-plane.view.v1', array fields tasks/lanes/pairs/events, and a projection with finite thresholds ta/ra. A payload failing any check throws 'Invalid control-plane view', indicating the server sent data that doesn't match the expected v1 schema.","triggerScenarios":"apply(data) is invoked (directly or via the /api/control-plane poll) with data that is null, has a wrong schemaVersion, has a non-array tasks/lanes/pairs/events field, or lacks a projection.agents array or finite thresholds.ta/thresholds.ra.","commonSituations":"Server and client versions disagree (schema changed but cache served an old page); a proxy returned an HTML error page parsed loosely; the snapshot builder emitted a partial/empty payload; stale cached JSON in localStorage or a CDN.","solutions":["Hard-reload the control-plane page so the client JS matches the server version","Inspect the /api/control-plane response and verify schemaVersion === 'ecc.control-plane.view.v1' and all required array/threshold fields","Update the server and client to the same version if you pinned one of them","Fix the snapshot builder on the server so it always emits the full v1 view shape"],"exampleFix":"// before\nfetch('/api/control-plane').then(r => r.json()).then(apply);\n// after\nfetch('/api/control-plane').then(r => r.json()).then(data => {\n  if (data && data.schemaVersion === 'ecc.control-plane.view.v1') apply(data);\n  else console.warn('skipping incompatible view payload', data && data.schemaVersion);\n});","handlingStrategy":"type-guard","validationCode":"function isValidView(d) {\n  return !!d && d.schemaVersion === 'ecc.control-plane.view.v1'\n    && ['tasks','lanes','pairs','events'].every(k => Array.isArray(d[k]))\n    && d.projection && Array.isArray(d.projection.agents)\n    && d.thresholds && Number.isFinite(d.thresholds.ta) && Number.isFinite(d.thresholds.ra);\n}\n// call apply only if isValidView(data)","typeGuard":"const isValidView = (d) => !!d && d.schemaVersion === 'ecc.control-plane.view.v1' && ['tasks','lanes','pairs','events'].every(k => Array.isArray(d[k])) && d.projection && Array.isArray(d.projection.agents) && d.thresholds && Number.isFinite(d.thresholds.ta) && Number.isFinite(d.thresholds.ra);","tryCatchPattern":"try { apply(data); } catch (e) {\n  if (e.message === 'Invalid control-plane view') setStatus('incompatible view payload; reload page');\n  else throw e;\n}","preventionTips":["Keep client JS and server schema versions in lockstep (hard reload after upgrades)","Validate payloads before apply when fetching from proxies/CDNs","Ensure the snapshot builder always emits all required arrays","Avoid caching /api/control-plane responses across schema versions"],"tags":["schema","validation","ui"],"backgroundTag":"schema-validation-failed","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"}