affaan-m/ECC · error · Error
Canonical session snapshot requires workers
Error message
Canonical session snapshot requires workers[${index}].outputs to be an object What it means
validateCanonicalSnapshot throws this when a worker has no outputs object. The canonical schema requires workers[i].outputs to contain summary, validation, and remainingRisks, each an array of strings, describing what the worker produced. Without it, consumers reading progress summaries would need null checks everywhere.
Solutions
- Add an outputs object with summary: [], validation: [], remainingRisks: [] (empty arrays are valid) to the worker.
- Ensure the worker lifecycle code initializes outputs at creation time rather than lazily.
- Regenerate the snapshot via the current normalize*Session adapters.
- Validate snapshots in CI with validateCanonicalSnapshot to catch missing outputs blocks.
Example fix
// before
worker.outputs = null;
// after
worker.outputs = { summary: [], validation: [], remainingRisks: [] }; Defensive patterns
Strategy: validation
Validate before calling
const outputsOk = snapshot.workers.every(w => w && w.outputs && typeof w.outputs === 'object' && Array.isArray(w.outputs.summary) && Array.isArray(w.outputs.validation) && Array.isArray(w.outputs.remainingRisks));
if (!outputsOk) throw new Error('every worker needs outputs { summary, validation, remainingRisks } arrays'); Type guard
function hasOutputs(w) { return !!w && typeof w.outputs === 'object' && w.outputs !== null && Array.isArray(w.outputs.summary); } Try / catch
try { persistCanonicalSnapshot(snapshot); } catch (err) { if (String(err.message).includes('.outputs to be an object')) { console.error('Worker missing outputs block:', err.message); /* scaffold empty outputs and retry */ } else { throw err; } } Prevention
- Initialize outputs as { summary: [], validation: [], remainingRisks: [] } when a worker is created.
- Never assign null to outputs; push into the arrays instead.
- Rebuild snapshots via current adapters rather than patching old persisted JSON.
- Add snapshot-shape assertions to CI tests.
When it happens
Trigger: Persisting or normalizing a snapshot whose worker omits outputs, sets it to null, or assigns a non-object such as an array or string.
Common situations: Workers created mid-session before any output was recorded but persisted without the empty scaffold; snapshots imported from older formats; hand-written test fixtures missing the outputs block.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Canonical session snapshot requires aggregates.healths to…
- Canonical session snapshot requires aggregates.states to be…
- Canonical session snapshot requires aggregates to be an…
- Canonical session snapshot requires aggregates.workerCount…
- Canonical session snapshot requires workers
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/0826dcbc545992ef.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/session-adapters/canonical-session.js:223
if (!isObject(worker.runtime)) {
throw new Error(`Canonical session snapshot requires workers[${index}].runtime to be an object`);
}
ensureString(worker.runtime.kind, `workers[${index}].runtime.kind`);
ensureOptionalString(worker.runtime.command, `workers[${index}].runtime.command`);
ensureBoolean(worker.runtime.active, `workers[${index}].runtime.active`);
ensureBoolean(worker.runtime.dead, `workers[${index}].runtime.dead`);
if (!isObject(worker.intent)) {
throw new Error(`Canonical session snapshot requires workers[${index}].intent to be an object`);
}
ensureStringAllowEmpty(worker.intent.objective, `workers[${index}].intent.objective`);
ensureArrayOfStrings(worker.intent.seedPaths, `workers[${index}].intent.seedPaths`);
if (!isObject(worker.outputs)) {
throw new Error(`Canonical session snapshot requires workers[${index}].outputs to be an object`);
}
ensureArrayOfStrings(worker.outputs.summary, `workers[${index}].outputs.summary`);
ensureArrayOfStrings(worker.outputs.validation, `workers[${index}].outputs.validation`);
ensureArrayOfStrings(worker.outputs.remainingRisks, `workers[${index}].outputs.remainingRisks`);
if (!isObject(worker.artifacts)) {
throw new Error(`Canonical session snapshot requires workers[${index}].artifacts to be an object`);
}
});
if (!isObject(snapshot.aggregates)) {
throw new Error('Canonical session snapshot requires aggregates to be an object');
}
ensureInteger(snapshot.aggregates.workerCount, 'aggregates.workerCount');
if (snapshot.aggregates.workerCount !== snapshot.workers.length) {
throw new Error('Canonical session snapshot requires aggregates.workerCount to match workers.length');View on GitHub (pinned to 8321021c54)