{"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":"exception","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/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/canonical-session.js#L173-L209","documentation":"Thrown by validateCanonicalSnapshot when snapshot.workers is not an array. Workers is the list of agent runtimes in the session; even a session with no workers must supply an empty array so aggregates and state derivation have a defined input.","triggerScenarios":"A snapshot where workers is null, undefined, an object, or a single worker object instead of an array. Happens when an adapter assigns a single worker without wrapping it in [], or omits the key entirely.","commonSituations":"A normalize function assigning worker instead of [worker]; a hand-built snapshot that forgets the workers key; a transform that converts workers to an object keyed by id.","solutions":["Always assign an array (possibly empty) to workers.","Use buildAggregates(workers) alongside it so counts stay consistent.","Wrap single workers in an array literal when constructing."],"exampleFix":"// before\nvalidateCanonicalSnapshot({ ..., workers: singleWorker, aggregates: { workerCount: 1 } });\n\n// after\nvalidateCanonicalSnapshot({ ..., workers: [singleWorker], aggregates: buildAggregates([singleWorker]) });","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(snapshot.workers)) {\n  throw new Error('snapshot.workers must be an array');\n}","typeGuard":"function hasWorkersArray(s) {\n  return s && typeof s === 'object' && Array.isArray(s.workers);\n}","tryCatchPattern":null,"preventionTips":["Always assign an array (possibly empty) to workers.","Wrap single workers in [ ] and pair with buildAggregates."],"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"}