{"record":{"id":"c57fa26dae80a1de","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-must-be-an-object","errorCode":null,"errorMessage":"Canonical session snapshot must be an object","messagePattern":"Canonical session snapshot must be an object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":164,"sourceCode":"  const failedCount = (workerStates.failed || 0) + (workerStates.error || 0);\n  if (failedCount > 0) {\n    return 'failed';\n  }\n\n  const completedCount = (workerStates.completed || 0)\n    + (workerStates.succeeded || 0)\n    + (workerStates.success || 0)\n    + (workerStates.done || 0);\n  if (completedCount === totalWorkers) {\n    return 'completed';\n  }\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","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/canonical-session.js#L146-L182","documentation":"Thrown at the top of validateCanonicalSnapshot when the snapshot argument is not a plain object (is null, an array, a primitive, or undefined). This is the outermost shape guard before any field validation runs.","triggerScenarios":"Calling validateCanonicalSnapshot(null), validateCanonicalSnapshot([]), validateCanonicalSnapshot('string'), validateCanonicalSnapshot(undefined), or passing a JSON.parse result that is an array at the top level.","commonSituations":"A recorded snapshot file whose top-level JSON is an array instead of an object; a code path that passes a list of snapshots instead of one; a deserialization that returned null; a refactor that passes the wrong variable.","solutions":["Confirm the snapshot is a single object before validating.","If loading from a file, check the parsed value is an object (not array) before use.","Loop over arrays of snapshots individually rather than passing the array."],"exampleFix":"// before\nvalidateCanonicalSnapshot(JSON.parse(raw)); // raw parses to an array\n\n// after\nconst parsed = JSON.parse(raw);\nconst snapshot = Array.isArray(parsed) ? parsed[0] : parsed;\nif (!snapshot || typeof snapshot !== 'object') throw new Error('No snapshot');\nvalidateCanonicalSnapshot(snapshot);","handlingStrategy":"type-guard","validationCode":"const parsed = JSON.parse(raw);\nif (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n  throw new Error('Snapshot must be a single object');\n}\nvalidateCanonicalSnapshot(parsed);","typeGuard":"function isPlainObject(v) {\n  return Boolean(v) && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Check the top-level parsed shape before validating.","Pass one snapshot at a time, never an array of snapshots."],"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"}