{"record":{"id":"d50aa5cf088b5ca4","repo":"affaan-m/ECC","slug":"memory-document-sourcepath-has-no-closing-front","errorCode":null,"errorMessage":"Memory document ${sourcePath} has no closing frontmatter marker.","messagePattern":"Memory document (.+?) has no closing frontmatter marker\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":258,"sourceCode":"  }\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]),\n    };\n  }, { values: {}, seen: new Set() });\n\n  const missing = FRONTMATTER_FIELDS\n    .map(([, objectKey]) => objectKey)\n    .filter(objectKey => !parsed.seen.has(objectKey));\n  if (missing.length > 0) {\n    throw new Error(`Memory document ${sourcePath} is missing fields: ${missing.join(', ')}.`);\n  }\n","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L240-L276","documentation":"Thrown by parseMemoryDocument() when the regex /\\r?\\n---(?=\\r?\\n|$)/ finds no match in the remainder after the opening marker. The closing frontmatter marker must be a line containing exactly '---' preceded by a newline and followed by a newline or end-of-string. Without it, the parser cannot tell where metadata ends and body begins.","triggerScenarios":"A file with an opening '---\\n' but no closing marker. A closing marker '---   ' with trailing spaces. A closing marker on the same line as content. A file truncated mid-frontmatter by a crashed write. A document with four dashes '----' instead of three.","commonSituations":"Editor that strips trailing newlines, leaving '---' at EOF without a following newline. Hand-edit that deleted the closing marker. Partial write from a process killed mid-save. AI agent that emitted only an opening marker.","solutions":["Inspect the file and add a '\\n---\\n' line after the last frontmatter field.","Ensure the closing marker is exactly three dashes on its own line with no trailing spaces.","If using a text editor, turn off 'trim trailing whitespace' or 'ensure newline at EOF' for vault files, or always regenerate via serializeMemoryDocument().","Restore from version control if a partial write is suspected."],"exampleFix":"// before\n---\ntitle: \"x\"\nkind: \"note\"\nbody text starts here without a closing marker\n\n// after\n---\ntitle: \"x\"\nkind: \"note\"\n---\n\nbody text starts here","handlingStrategy":"validation","validationCode":"const opening = /^---\\r?\\n/.exec(source);\nif (opening && !/\\r?\\n---(?=\\r?\\n|$)/.test(source.slice(opening[0].length))) {\n  throw new Error('memory document is missing the closing --- frontmatter marker');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always emit '\\n---\\n' after the last frontmatter field when generating files.","Use serializeMemoryDocument() — its output is `---\\\\n${metadata}\\\\n---${body}\\\\n`.","Avoid editor options that strip trailing newlines from vault files."],"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"}