{"record":{"id":"c711ab6e5c531278","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-fieldpath-t-c711ab","errorCode":null,"errorMessage":"Canonical session snapshot requires ${fieldPath} to be a boolean","messagePattern":"Canonical session snapshot requires (.+?) to be a boolean","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":53,"sourceCode":"    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a non-empty string`);\n  }\n}\n\nfunction ensureStringAllowEmpty(value, fieldPath) {\n  if (typeof value !== 'string') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a string`);\n  }\n}\n\nfunction ensureOptionalString(value, fieldPath) {\n  if (value !== null && value !== undefined && typeof value !== 'string') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a string or null`);\n  }\n}\n\nfunction ensureBoolean(value, fieldPath) {\n  if (typeof value !== 'boolean') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a boolean`);\n  }\n}\n\nfunction ensureArrayOfStrings(value, fieldPath) {\n  if (!Array.isArray(value) || value.some(item => typeof item !== 'string')) {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be an array of strings`);\n  }\n}\n\nfunction ensureInteger(value, fieldPath) {\n  if (!Number.isInteger(value) || value < 0) {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a non-negative integer`);\n  }\n}\n\nconst STALE_THRESHOLD_MS = 5 * 60 * 1000;\n\nfunction parseUpdatedMs(updated) {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/canonical-session.js#L35-L71","documentation":"Thrown by the ensureBoolean helper when a field that must be a boolean is not. Applied to workers[i].runtime.active and workers[i].runtime.dead — these drive health derivation and must be strict booleans.","triggerScenarios":"A worker.runtime.active set to 1, 'true', undefined, or null; runtime.dead set to a truthy non-boolean. Often happens when an adapter forwards a source field without Boolean() coercion.","commonSituations":"A source pane record where active is 0/1 instead of false/true; an adapter that left active as undefined; a JSON parse that produced a number where a boolean was expected; test data using truthy integers.","solutions":["Always coerce with Boolean() when building runtime: active: Boolean(pane && pane.active).","Ensure source adapters emit strict booleans for these fields.","Validate fixtures before persisting a snapshot."],"exampleFix":"// before\nruntime: { active: pane.active, dead: pane.dead, ... } // pane.active is 0/1\n\n// after\nruntime: { active: Boolean(pane && pane.active), dead: Boolean(pane && pane.dead), ... }","handlingStrategy":"type-guard","validationCode":"// Force strict booleans when constructing runtime.\nactive: Boolean(pane && pane.active),\ndead: Boolean(pane && pane.dead),","typeGuard":"function isBool(v) { return typeof v === 'boolean'; }","tryCatchPattern":null,"preventionTips":["Always coerce active/dead with Boolean() at the source.","Avoid forwarding 0/1 or 'true'/'false' strings for these fields."],"tags":["validation","session-schema","canonical-session"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}