{"record":{"id":"c6b4f58147838d55","repo":"affaan-m/ECC","slug":"canonical-session-snapshot-requires-fieldpath-t","errorCode":null,"errorMessage":"Canonical session snapshot requires ${fieldPath} to be a non-empty string","messagePattern":"Canonical session snapshot requires (.+?) to be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/canonical-session.js","lineNumber":35,"sourceCode":"    .trim()\n    .replace(/[^A-Za-z0-9._-]+/g, '_')\n    .replace(/^_+|_+$/g, '') || 'unknown';\n}\n\nfunction parseContextSeedPaths(context) {\n  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`);","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/session-adapters/canonical-session.js#L17-L53","documentation":"ensureString() is the validator used by validateCanonicalSessionSnapshot() to enforce the canonical session snapshot schema: required string fields must be actual non-empty strings. When a field at fieldPath (e.g. 'meta.source', 'session.id') is absent, undefined, not a string, or an empty string, the adapter throws this error naming the exact field path. It protects downstream consumers from malformed imported session data.","triggerScenarios":"Importing/adapting a session snapshot where a required field is missing or empty: JSON produced by another tool lacking 'meta.source'; a hand-written snapshot with id: ''; a field renamed upstream so the adapter reads undefined; parsing a transcript that yielded null for a field.","commonSituations":"Cross-harness session migration (Claude/Codex/Cursor exports with differing schemas); older session files predating a schema field addition; truncated or corrupted export files; manually edited session JSON with a blanked field; adapter version older than the snapshot format.","solutions":["Read the fieldPath in the message and populate that field with a non-empty string in the snapshot JSON.","Regenerate the snapshot with the exporting tool at a compatible/recent version so all required fields are emitted.","If migrating between harness formats, run the export through the library's current adapter/exporter rather than hand-editing JSON.","Check for schema changes: diff your snapshot against the documented canonical snapshot format for the installed version."],"exampleFix":"// before\n{ \"session\": { \"id\": \"\", \"title\": \"My session\" } }\n// throws: requires session.id to be a non-empty string\n// after\n{ \"session\": { \"id\": \"a1b2c3d4\", \"title\": \"My session\" } }","handlingStrategy":"validation","validationCode":"function validateSnapshotBasics(snap) {\n  for (const p of [['session', snap.session], ['session.id', snap.session && snap.session.id], ['meta.source', snap.meta && snap.meta.source]]) {\n    const [name, val] = p;\n    if (typeof val !== 'string' || val.length === 0) {\n      throw new Error(`Snapshot field ${name} must be a non-empty string before import`);\n    }\n  }\n}\n// run validateSnapshotBaseline(json) before handing the snapshot to the adapter","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  validateCanonicalSessionSnapshot(raw);\n} catch (e) {\n  const m = /requires (.+?) to be a non-empty string/.exec(e.message);\n  if (m) {\n    console.error(`Snapshot field '${m[1]}' is missing/empty — regenerate the export or fill the field.`);\n  } else throw e;\n}","preventionTips":["Regenerate snapshots with the current exporter instead of hand-editing session JSON.","Validate exports against the canonical schema right after producing them.","Keep exporter and adapter versions in sync when migrating between harnesses.","Never write empty strings into required identifier fields (id, source) during edits or merges."],"tags":["schema-validation","session","serialization","data-import"],"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"}