{"record":{"id":"3117b6f53338d528","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-session-to-be","errorCode":null,"errorMessage":"Canonical session snapshot requires session to be an object","messagePattern":"Canonical session snapshot requires session to be an object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":175,"sourceCode":"  }\n\n  return 'idle';\n}\n\nfunction validateCanonicalSnapshot(snapshot) {\n  if (!isObject(snapshot)) {\n    throw new Error('Canonical session snapshot must be an object');\n  }\n\n  ensureString(snapshot.schemaVersion, 'schemaVersion');\n  if (snapshot.schemaVersion !== SESSION_SCHEMA_VERSION) {\n    throw new Error(`Unsupported canonical session schema version: ${snapshot.schemaVersion}`);\n  }\n\n  ensureString(snapshot.adapterId, 'adapterId');\n\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","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/canonical-session.js#L157-L193","documentation":"Thrown by validateCanonicalSnapshot when snapshot.session is not a plain object. The session sub-object carries id, kind, state, repoRoot, and sourceTarget, all of which are required for a canonical snapshot to be meaningful.","triggerScenarios":"A snapshot where session is null, undefined, an array, or a string. Happens when an adapter omits the session block or assigns it to a primitive by mistake.","commonSituations":"A normalize function that forgot to include the session key; a hand-edited snapshot missing the session object; a transform that flattened session fields into the top level.","solutions":["Always construct the session object explicitly with id/kind/state/sourceTarget.","Validate presence of snapshot.session as an object before calling validateCanonicalSnapshot.","Use the exported normalize* helpers, which build the session block for you."],"exampleFix":"// before\nvalidateCanonicalSnapshot({ schemaVersion, adapterId, workers: [] }); // no session\n\n// after\nvalidateCanonicalSnapshot({\n  schemaVersion, adapterId,\n  session: { id, kind, state, repoRoot: null, sourceTarget },\n  workers: [],\n  aggregates: buildAggregates([])\n});","handlingStrategy":"type-guard","validationCode":"if (!snapshot.session || typeof snapshot.session !== 'object' || Array.isArray(snapshot.session)) {\n  throw new Error('snapshot.session must be an object');\n}","typeGuard":"function hasSessionObject(s) {\n  return s && typeof s === 'object' && !Array.isArray(s)\n    && s.session && typeof s.session === 'object' && !Array.isArray(s.session);\n}","tryCatchPattern":null,"preventionTips":["Always construct the session block explicitly in normalize functions.","Include id, kind, state, repoRoot, and sourceTarget when building it."],"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"}