{"record":{"id":"2a759830be7dcae6","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-workers-inde-2a7598","errorCode":null,"errorMessage":"Canonical session snapshot requires workers[${index}].intent to be an object","messagePattern":"Canonical session snapshot requires workers\\[(.+?)\\]\\.intent to be an object","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":216,"sourceCode":"\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\n    ensureString(worker.runtime.kind, `workers[${index}].runtime.kind`);\n    ensureOptionalString(worker.runtime.command, `workers[${index}].runtime.command`);\n    ensureBoolean(worker.runtime.active, `workers[${index}].runtime.active`);\n    ensureBoolean(worker.runtime.dead, `workers[${index}].runtime.dead`);\n\n    if (!isObject(worker.intent)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}].intent to be an object`);\n    }\n\n    ensureStringAllowEmpty(worker.intent.objective, `workers[${index}].intent.objective`);\n    ensureArrayOfStrings(worker.intent.seedPaths, `workers[${index}].intent.seedPaths`);\n\n    if (!isObject(worker.outputs)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}].outputs to be an object`);\n    }\n\n    ensureArrayOfStrings(worker.outputs.summary, `workers[${index}].outputs.summary`);\n    ensureArrayOfStrings(worker.outputs.validation, `workers[${index}].outputs.validation`);\n    ensureArrayOfStrings(worker.outputs.remainingRisks, `workers[${index}].outputs.remainingRisks`);\n\n    if (!isObject(worker.artifacts)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}].artifacts to be an object`);\n    }\n  });\n","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/session-adapters/canonical-session.js#L198-L234","documentation":"This error indicates a worker entry lacks a valid intent object. The canonical schema requires workers[i].intent to expose objective (string, may be empty) and seedPaths (array of strings), capturing what the worker was asked to do. validateCanonicalSnapshot enforces this before persistence or normalization.","triggerScenarios":"Calling persistCanonicalSnapshot or a normalize* adapter with a worker whose intent is missing, null, or a non-object (string/number/array).","commonSituations":"Snapshot builders from older ECC versions that omitted the intent block; test fixtures copied from pre-intent snapshots; a migration script that flattened intent into top-level worker fields.","solutions":["Add an intent object with objective (string, can be '') and seedPaths ([] is valid) to the offending worker.","Update the snapshot producer/adapter to always emit intent per worker.","Regenerate the snapshot with the current adapters instead of reusing stale persisted JSON.","Add a unit test asserting validateCanonicalSnapshot passes on every fixture snapshot."],"exampleFix":"// before\nworker.intent = undefined;\n// after\nworker.intent = { objective: 'refactor auth module', seedPaths: ['src/auth/'] };","handlingStrategy":"validation","validationCode":"const intentOk = snapshot.workers.every(w => w && w.intent && typeof w.intent === 'object' && typeof w.intent.objective === 'string' && Array.isArray(w.intent.seedPaths));\nif (!intentOk) throw new Error('every worker needs intent { objective, seedPaths }');","typeGuard":"function hasIntent(w) { return !!w && typeof w.intent === 'object' && w.intent !== null && typeof w.intent.objective === 'string' && Array.isArray(w.intent.seedPaths); }","tryCatchPattern":"try { persistCanonicalSnapshot(snapshot); } catch (err) { if (String(err.message).includes('.intent to be an object')) { console.error('Worker missing intent block:', err.message); /* attach intent scaffold and retry */ } else { throw err; } }","preventionTips":["Create workers with an intent scaffold even when the objective is empty ('' is allowed).","Derive intent from task data at spawn time, not lazily on first write.","Validate the snapshot before persisting to catch schema drift early.","Keep test fixtures updated with the current canonical schema."],"tags":["schema-validation","session-snapshot"],"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"}