{"record":{"id":"a6507207a2547f18","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-fieldpath-t-a65072","errorCode":null,"errorMessage":"Canonical session snapshot requires ${fieldPath} to be a string or null","messagePattern":"Canonical session snapshot requires (.+?) to be a string or null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":47,"sourceCode":"    .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`);\n  }\n}\n\nfunction ensureInteger(value, fieldPath) {\n  if (!Number.isInteger(value) || value < 0) {\n    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a non-negative integer`);","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/session-adapters/canonical-session.js#L29-L65","documentation":"ensureOptionalString validates that a snapshot field is either a string or null. This error means the field at fieldPath was set to some other type (number, boolean, object, or undefined is allowed only via the explicit null/undefined check — actually undefined passes, so this fired on a concrete non-string value). It keeps the canonical snapshot schema strict so downstream consumers can rely on string|null types.","triggerScenarios":"Calling validateCanonicalSnapshot (via persistCanonicalSnapshot or a normalize* adapter) with an optional string field such as session.repoRoot set to e.g. 42 or { raw: '...' } instead of a string or null.","commonSituations":"Mapping an object (like a worktree handle) into repoRoot instead of its path string; adapters reading config where a path field was parsed as YAML/JSON with a non-string type; older adapter versions producing different field shapes.","solutions":["Inspect the fieldPath named in the error and print its type (typeof snapshot.session.repoRoot)","Convert the value to its string form (path.toString(), String(value)) before normalizing","Use null explicitly for absent values instead of numbers/objects","Re-run the snapshot through the matching normalize* adapter for your source format"],"exampleFix":"// before\nsnapshot.session.repoRoot = { path: '/repo' };\n// after\nsnapshot.session.repoRoot = '/repo';","handlingStrategy":"validation","validationCode":"const okOpt = (v) => v === null || typeof v === 'string';","typeGuard":"const isOptionalString = (v) => v == null || typeof v === 'string';","tryCatchPattern":"try { persistCanonicalSnapshot(s); } catch (e) { if (/string or null/.test(e.message)) { /* coerce */ } else throw e; }","preventionTips":["Use null for absent optionals","Coerce config values to strings at boundaries"],"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"}