{"record":{"id":"b894bbf2d5fb73c7","repo":"affaan-m/ECC","slug":"memory-document-sourcepath-must-start-with","errorCode":null,"errorMessage":"Memory document ${sourcePath} must start with --- frontmatter.","messagePattern":"Memory document (.+?) must start with --- frontmatter\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":248,"sourceCode":"    throw new Error(`Unknown memory frontmatter field in ${sourcePath}.`);\n  }\n  if (seen.has(objectKey)) {\n    throw new Error(`Duplicate memory frontmatter field in ${sourcePath}.`);\n  }\n  const rawValue = line.slice(separator + 1).trim();\n  try {\n    return { objectKey, value: JSON.parse(rawValue) };\n  } catch {\n    throw new Error(`Memory frontmatter field in ${sourcePath} must use a JSON value.`);\n  }\n}\n\nfunction parseMemoryDocument(source, sourcePath = '<memory>') {\n  const openingMarker = typeof source === 'string'\n    ? /^---\\r?\\n/.exec(source)\n    : null;\n  if (!openingMarker) {\n    throw new Error(`Memory document ${sourcePath} must start with --- frontmatter.`);\n  }\n  if (Buffer.byteLength(source, 'utf8') > MAX_DOCUMENT_BYTES) {\n    throw new Error(`Memory document ${sourcePath} is too large.`);\n  }\n\n  const frontmatterStart = openingMarker[0].length;\n  const remainder = source.slice(frontmatterStart);\n  const closingMarker = /\\r?\\n---(?=\\r?\\n|$)/.exec(remainder);\n  if (!closingMarker) {\n    throw new Error(`Memory document ${sourcePath} has no closing frontmatter marker.`);\n  }\n\n  const frontmatterSource = remainder.slice(0, closingMarker.index);\n  const parsed = frontmatterSource.split(/\\r?\\n/).reduce((state, line) => {\n    const next = parseFrontmatterLine(line, sourcePath, state.seen);\n    return {\n      values: { ...state.values, [next.objectKey]: next.value },\n      seen: new Set([...state.seen, next.objectKey]),","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L230-L266","documentation":"Thrown by parseMemoryDocument() when the source does not begin with the opening frontmatter marker '---\\n' (or '---\\r\\n'), or when source is not a string at all. The marker must be the very first bytes of the document — leading whitespace, a BOM, or a shebang will not match. The check uses /^---\\r?\\n/.","triggerScenarios":"parseMemoryDocument('') on an empty file. parseMemoryDocument('title: x') where the opening marker was stripped. A file that starts with a UTF-8 BOM (\\uFEFF). A file edited in Windows that begins with '\\r\\n---\\r\\n'. Passing a Buffer instead of a string. Calling parseMemoryDocument on a non-memory .md file.","commonSituations":"Vault directory got mixed with regular markdown files. Editor inserted a BOM on save. Network transfer that strips the first line. Bug in a wrapper that called .trim() on the source before parsing (removing leading '---' if it was followed by '\\n' only at start).","solutions":["Confirm the file begins with exactly '---\\n' as its first four bytes; use hexdump -C file | head -1.","Strip a leading BOM before parsing: source = source.replace(/^\\uFEFF/, '').","If you called parseMemoryDocument(fs.readFileSync(path,'utf8')) and got this, check that the file is not empty.","Use saveMemory() to author files so the opening marker is always correct."],"exampleFix":"// before\n// file content:  \\uFEFF---\\ntitle: \"x\"\\n---\\nbody\\n\nconst mem = parseMemoryDocument(source, path);\n\n// after\nconst mem = parseMemoryDocument(source.replace(/^\\uFEFF/, ''), path);","handlingStrategy":"validation","validationCode":"if (typeof source !== 'string' || !/^---\\r?\\n/.test(source.replace(/^\\uFEFF/, ''))) {\n  throw new Error('memory document must begin with ---\\\\n (BOM stripped if present)');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Author files with saveMemory() — the opening marker is always correct.","Disable BOM insertion in your editor for vault directories.","Do not call .trim() on source before parsing — it can mask the leading marker check."],"tags":["parsing","frontmatter","validation","memory-vault"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}