{"record":{"id":"e5513cca8ebc47df","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-fieldpath-t-e5513c","errorCode":null,"errorMessage":"Canonical session snapshot requires ${fieldPath} to be a string","messagePattern":"Canonical session snapshot requires (.+?) to be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":41,"sourceCode":"  if (typeof context !== 'string' || context.trim().length === 0) {\n    return [];\n  }\n\n  return context\n    .split('\\n')\n    .map(line => line.trim())\n    .filter(Boolean);\n}\n\nfunction ensureString(value, fieldPath) {\n  if (typeof value !== 'string' || value.length === 0) {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a non-empty string`);\n  }\n}\n\nfunction ensureStringAllowEmpty(value, fieldPath) {\n  if (typeof value !== 'string') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a string`);\n  }\n}\n\nfunction ensureOptionalString(value, fieldPath) {\n  if (value !== null && value !== undefined && typeof value !== 'string') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a string or null`);\n  }\n}\n\nfunction ensureBoolean(value, fieldPath) {\n  if (typeof value !== 'boolean') {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a boolean`);\n  }\n}\n\nfunction ensureArrayOfStrings(value, fieldPath) {\n  if (!Array.isArray(value) || value.some(item => typeof item !== 'string')) {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be an array of strings`);","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/session-adapters/canonical-session.js#L23-L59","documentation":"validateCanonicalSnapshot calls ensureStringAllowEmpty for fields that must be strings but may be empty. This error means one of those field paths held a non-string value (number, boolean, object, null, or undefined). The library throws it eagerly while validating a canonical session snapshot before persisting or normalizing it.","triggerScenarios":"Calling persistCanonicalSnapshot or any normalize* function with a snapshot where an allow-empty string field (validated via ensureStringAllowEmpty in canonical-session.js) is set to null, undefined, a number, or an object.","commonSituations":"Hand-written snapshot JSON where a field like session.repoRoot or a session id was omitted or typed as a number; adapters built against an older schema version; deserialized JSON from an external tool where empty fields became null.","solutions":["Log the full snapshot and find the field named in ${fieldPath} in the error message","Coerce or fix that field to a string (String(value), or null handling upstream)","If the field is genuinely optional, use null with the ensureOptionalString-validated path rather than undefined","Regenerate the snapshot via the official normalize* adapter functions instead of hand-constructing it"],"exampleFix":"// before\nsnapshot.session.repoRoot = undefined;\n// after\nsnapshot.session.repoRoot = '/worktrees/my-repo';","handlingStrategy":"validation","validationCode":"const ok = typeof snapshot?.schemaVersion === 'string' && typeof snapshot?.adapterId === 'string';","typeGuard":"const isString = (v) => typeof v === 'string';","tryCatchPattern":"try { persistCanonicalSnapshot(s); } catch (e) { if (/to be a string/.test(e.message)) { console.error(e.message); } else throw e; }","preventionTips":["Use adapters to build snapshots","Type-check fields before persisting","Avoid undefined for schema fields"],"tags":["validation","schema","type-mismatch"],"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"}