{"record":{"id":"01134c22ae10f33e","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-workers-to-be","errorCode":null,"errorMessage":"Canonical session snapshot requires workers to be an array","messagePattern":"Canonical session snapshot requires workers to be an array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":191,"sourceCode":"\n  if (!isObject(snapshot.session)) {\n    throw new Error('Canonical session snapshot requires session to be an object');\n  }\n\n  ensureString(snapshot.session.id, 'session.id');\n  ensureString(snapshot.session.kind, 'session.kind');\n  ensureString(snapshot.session.state, 'session.state');\n  ensureOptionalString(snapshot.session.repoRoot, 'session.repoRoot');\n\n  if (!isObject(snapshot.session.sourceTarget)) {\n    throw new Error('Canonical session snapshot requires session.sourceTarget to be an object');\n  }\n\n  ensureString(snapshot.session.sourceTarget.type, 'session.sourceTarget.type');\n  ensureString(snapshot.session.sourceTarget.value, 'session.sourceTarget.value');\n\n  if (!Array.isArray(snapshot.workers)) {\n    throw new Error('Canonical session snapshot requires workers to be an array');\n  }\n\n  snapshot.workers.forEach((worker, index) => {\n    if (!isObject(worker)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}] to be an object`);\n    }\n\n    ensureString(worker.id, `workers[${index}].id`);\n    ensureString(worker.label, `workers[${index}].label`);\n    ensureString(worker.state, `workers[${index}].state`);\n    ensureString(worker.health, `workers[${index}].health`);\n    ensureOptionalString(worker.branch, `workers[${index}].branch`);\n    ensureOptionalString(worker.worktree, `workers[${index}].worktree`);\n\n    if (!isObject(worker.runtime)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}].runtime to be an object`);\n    }\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/session-adapters/canonical-session.js#L173-L209","documentation":"validateCanonicalSnapshot requires snapshot.workers to be an array (worker entries are then validated per index). This error throws when workers is null, undefined, an object, or a string. Even a snapshot with no workers must supply an empty array, not omit the key.","triggerScenarios":"Building a snapshot without a workers key; JSON where workers was null; passing a single worker object instead of an array containing it; a Map or Set being serialized into an object shape.","commonSituations":"Test fixtures that omit workers; hand-written snapshots; older schema versions where workers was optional; merging partial snapshots that overwrite workers with null.","solutions":["Set snapshot.workers = [] when there are no workers","Wrap a single worker in an array: workers = [worker]","Ensure workers is a plain JSON array (convert Maps/Sets with Array.from)","Regenerate the snapshot through the appropriate normalize* adapter"],"exampleFix":"// before\n{ \"session\": {...}, \"workers\": null }\n// after\n{ \"session\": {...}, \"workers\": [] }","handlingStrategy":"type-guard","validationCode":"if (!hasWorkersArray(snap)) throw new TypeError('workers must be an array');","typeGuard":"const hasWorkersArray = (v) => Array.isArray(v?.workers);","tryCatchPattern":"try { persistCanonicalSnapshot(snap); } catch (e) { if (/workers to be an array/.test(e.message)) { snap.workers = snap.workers ? [snap.workers] : []; } else throw e; }","preventionTips":["Default workers to []","Never set workers to null"],"tags":["validation","schema","array","missing-field"],"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"}