affaan-m/ECC · error · Error
Canonical session snapshot requires workers to be an array
Error message
Canonical session snapshot requires workers to be an array
What it means
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.
Source
Thrown at scripts/lib/session-adapters/canonical-session.js:191
if (!isObject(snapshot.session)) {
throw new Error('Canonical session snapshot requires session to be an object');
}
ensureString(snapshot.session.id, 'session.id');
ensureString(snapshot.session.kind, 'session.kind');
ensureString(snapshot.session.state, 'session.state');
ensureOptionalString(snapshot.session.repoRoot, 'session.repoRoot');
if (!isObject(snapshot.session.sourceTarget)) {
throw new Error('Canonical session snapshot requires session.sourceTarget to be an object');
}
ensureString(snapshot.session.sourceTarget.type, 'session.sourceTarget.type');
ensureString(snapshot.session.sourceTarget.value, 'session.sourceTarget.value');
if (!Array.isArray(snapshot.workers)) {
throw new Error('Canonical session snapshot requires workers to be an array');
}
snapshot.workers.forEach((worker, index) => {
if (!isObject(worker)) {
throw new Error(`Canonical session snapshot requires workers[${index}] to be an object`);
}
ensureString(worker.id, `workers[${index}].id`);
ensureString(worker.label, `workers[${index}].label`);
ensureString(worker.state, `workers[${index}].state`);
ensureString(worker.health, `workers[${index}].health`);
ensureOptionalString(worker.branch, `workers[${index}].branch`);
ensureOptionalString(worker.worktree, `workers[${index}].worktree`);
if (!isObject(worker.runtime)) {
throw new Error(`Canonical session snapshot requires workers[${index}].runtime to be an object`);
}
View on GitHub (pinned to 01e15490f0)
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.
Example fix
// before
validateCanonicalSnapshot({ ..., workers: singleWorker, aggregates: { workerCount: 1 } });
// after
validateCanonicalSnapshot({ ..., workers: [singleWorker], aggregates: buildAggregates([singleWorker]) }); Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(snapshot.workers)) {
throw new Error('snapshot.workers must be an array');
} Type guard
function hasWorkersArray(s) {
return s && typeof s === 'object' && Array.isArray(s.workers);
} Prevention
- Always assign an array (possibly empty) to workers.
- Wrap single workers in [ ] and pair with buildAggregates.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Canonical session snapshot requires ${fieldPath} to be a non
- Canonical session snapshot requires ${fieldPath} to be a str
- Canonical session snapshot requires ${fieldPath} to be a str
- Canonical session snapshot requires ${fieldPath} to be a boo
- Canonical session snapshot requires ${fieldPath} to be an ar
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/01134c22ae10f33e.
Report an issue: GitHub.