affaan-m/ECC · error · Error

Memory frontmatter field in

Error message

Memory frontmatter field in ${sourcePath} must use a JSON value.

What it means

Frontmatter values must be valid JSON (parseFrontmatterLine runs JSON.parse on the text after the colon). This allows typed values (numbers, arrays for targetHarnesses) but means bare strings must be quoted. Unquoted or malformed values fail JSON.parse and are rejected.

Solutions

  1. Quote string values with double quotes: title: "Deploy notes".
  2. Ensure arrays are JSON arrays with quoted elements: targetHarnesses: ["claude"].
  3. Remove YAML-only syntax (single quotes, unquoted scalars, comments) from frontmatter lines.
  4. Test the value with JSON.parse (e.g. `node -e "JSON.parse('[1]' )"`) or re-save via the library to serialize values correctly.

Example fix

// before
---
title: Deploy notes
targetHarnesses: [claude, codex]
---

// after
---
title: "Deploy notes"
targetHarnesses: ["claude", "codex"]
---
Defensive patterns

Strategy: validation

Validate before calling

for (const line of frontmatterLines) {
  const value = line.slice(line.indexOf(':') + 1).trim();
  JSON.parse(value); // throws locally if not valid JSON
}

Type guard

const isJsonValue = (s) => { try { JSON.parse(s); return true; } catch { return false; } };

Try / catch

try {
  parseMemoryDocument(source, path);
} catch (err) {
  if (err.message.includes('must use a JSON value')) {
    console.error('Frontmatter values in %s must be JSON — quote strings and use JSON arrays.', path);
  } else throw err;
}

Prevention

When it happens

Trigger: Frontmatter lines like `title: Deploy notes` (unquoted string), `targetHarnesses: [claude]` (unquoted array elements), trailing commas, single quotes, or YAML-style scalars such as `schema: '1'` that are not JSON.

Common situations: Users editing the vault markdown expecting YAML semantics (unquoted strings, comment lines with #, single quotes) instead of the actual `key: JSON value` format; templates generated by non-JSON emitters.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/4e8b00b1be059bfe. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/memory-vault-format.js:239

function parseFrontmatterLine(line, sourcePath, seen) {
  const separator = line.indexOf(':');
  if (separator <= 0) {
    throw new Error(`Invalid memory frontmatter line in ${sourcePath}.`);
  }
  const serializedKey = line.slice(0, separator).trim();
  const objectKey = FRONTMATTER_KEYS.get(serializedKey);
  if (!objectKey) {
    throw new Error(`Unknown memory frontmatter field in ${sourcePath}.`);
  }
  if (seen.has(objectKey)) {
    throw new Error(`Duplicate memory frontmatter field in ${sourcePath}.`);
  }
  const rawValue = line.slice(separator + 1).trim();
  try {
    return { objectKey, value: JSON.parse(rawValue) };
  } catch {
    throw new Error(`Memory frontmatter field in ${sourcePath} must use a JSON value.`);
  }
}

function parseMemoryDocument(source, sourcePath = '<memory>') {
  const openingMarker = typeof source === 'string'
    ? /^---\r?\n/.exec(source)
    : null;
  if (!openingMarker) {
    throw new Error(`Memory document ${sourcePath} must start with --- frontmatter.`);
  }
  if (Buffer.byteLength(source, 'utf8') > MAX_DOCUMENT_BYTES) {
    throw new Error(`Memory document ${sourcePath} is too large.`);
  }

  const frontmatterStart = openingMarker[0].length;
  const remainder = source.slice(frontmatterStart);
  const closingMarker = /\r?\n---(?=\r?\n|$)/.exec(remainder);
  if (!closingMarker) {

View on GitHub (pinned to 8321021c54)