{"record":{"id":"6f5c616e3aaf8db4","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-session-source","errorCode":null,"errorMessage":"Canonical session snapshot requires session.sourceTarget to be an object","messagePattern":"Canonical session snapshot requires session\\.sourceTarget to be an object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":184,"sourceCode":"\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\n  snapshot.workers.forEach((worker, index) => {\n    if (!isObject(worker)) {\n      throw new Error(`Canonical session snapshot requires workers[${index}] to be an object`);\n    }\n\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`);","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/canonical-session.js#L166-L202","documentation":"Thrown by validateCanonicalSnapshot when snapshot.session.sourceTarget is not a plain object. sourceTarget must carry a `type` and `value` string describing where the session originated (e.g. a repo path or socket), and is required so consumers can trace the session back to its source.","triggerScenarios":"A snapshot where sourceTarget is null, undefined, or a string. Common when an adapter is invoked without a source target argument, or when one was passed but not threaded into the session object.","commonSituations":"Calling normalizeClaudeHistorySession(session) without the second sourceTarget argument; building a snapshot by hand and forgetting sourceTarget; a refactor that dropped the parameter.","solutions":["Always pass a sourceTarget object of shape { type: string, value: string } to normalize functions.","Default sourceTarget to { type: 'unknown', value: '' } when no real source exists.","Construct sourceTarget from the adapter's origin (e.g. { type: 'repo', value: repoRoot })."],"exampleFix":"// before\nnormalizeClaudeHistorySession(session); // no sourceTarget -> session.sourceTarget missing\n\n// after\nnormalizeClaudeHistorySession(session, { type: 'claude-history', value: session.sessionPath });","handlingStrategy":"validation","validationCode":"// Always supply a sourceTarget to normalize functions.\nconst sourceTarget = { type: 'repo', value: repoRoot };\nnormalizeClaudeHistorySession(session, sourceTarget);","typeGuard":"function isSourceTarget(v) {\n  return v && typeof v === 'object'\n    && typeof v.type === 'string' && typeof v.value === 'string';\n}","tryCatchPattern":null,"preventionTips":["Pass sourceTarget as the second arg to every normalize* function.","Default to { type: 'unknown', value: '' } when no real source is available."],"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"}