affaan-m/ECC · error · Error

Duplicate memory frontmatter field in ${sourcePath}.

Error message

Duplicate memory frontmatter field in ${sourcePath}.

What it means

Thrown by parseFrontmatterLine() via the 'seen' Set when the same serialized key (normalised to its objectKey) appears twice in one frontmatter block. Duplicate fields create ambiguity about which value wins; rather than picking last/first, the parser rejects the document. This catches copy-paste errors and merge-conflict leftovers.

Source

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

  try {
    return FATAL_UTF8_DECODER.decode(buffer);
  } catch {
    throw new Error(`${label} must contain valid UTF-8 text.`);
  }
}

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.`);

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Open sourcePath and remove the duplicate line, keeping one canonical value.
  2. After a git merge, grep each vault file for repeated keys.
  3. Run doctorMemoryVault() to enumerate which files fail validation, then fix each.
  4. Regenerate via serializeMemoryDocument() to guarantee one of each field.

Example fix

// before
---
title: "handoff A"
kind: "handoff"
title: "handoff B"        // duplicate
---

// after
---
title: "handoff A"
kind: "handoff"
---
Defensive patterns

Strategy: validation

Validate before calling

const seen = new Set();
for (const line of frontmatterLines) {
  const key = line.slice(0, line.indexOf(':')).trim();
  if (seen.has(key)) throw new Error(`duplicate frontmatter key: ${key}`);
  seen.add(key);
}

Prevention

When it happens

Trigger: A git merge that left both versions of a field: 'title: "a"' and later 'title: "b"'. Copy-paste of a block that included the title twice. AI agent appending a 'kind:' line to a document that already had one. Editor template that pre-fills fields the user then re-added.

Common situations: Post-merge memory file never edited after conflict resolution. Repetitive templating workflow. Refactor that moved fields around but did not delete the originals.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/d5c8d532f02f3428. Report an issue: GitHub.