Memory-file Write/Edit silently rewrites YAML frontmatter (nests top-level keys, truncates `description` at #, slugifies `name`)

Open 💬 4 comments Opened May 21, 2026 by blanktech23

Summary

When a Markdown file under the memory directory is written via the Write or Edit tool, Claude Code silently rewrites its YAML frontmatter before the file reaches disk. Three transformations occur, none requested or opt-out-able:

  1. Top-level keys are nested under metadata: — every frontmatter key except name, description, and metadata is moved into a metadata: block.
  2. description: is truncated at the first # — an unquoted description containing # loses everything from the # onward (YAML treats it as a comment).
  3. name: is slugified — downcased and kebab-cased.

node_type: memory and originSessionId: <uuid> are also injected.

This breaks any tooling — user hooks, sync scripts, downstream parsers — that reads top-level frontmatter fields, because those fields are no longer where they were written.

Reproduction

Claude Code 2.1.146, macOS (arm64).

  1. Use the Write tool to create a .md file under the memory directory (~/.claude/projects/<project>/memory/) with:
---
name: Formatter Repro Test
description: Tracking PR #762 and issue #800 — note the # characters
type: feedback
triggers: ["alpha phrase", "beta phrase"]
session: false
---

Body text.
  1. Read the file back from disk.

Expected

Frontmatter preserved as written (whitespace normalization at most).

Actual

---
name: formatter-repro-test
description: Tracking PR
metadata:
  node_type: memory
  type: feedback
  triggers:
    - alpha phrase
    - beta phrase
  session: false
  originSessionId: <session-uuid>
---

Body text.
  • name: Formatter Repro Testformatter-repro-test
  • description: Tracking PR #762 and issue #800 — note the # charactersTracking PR (truncated at the first #)
  • type, triggers, session: relocated under metadata:

Impact

  • Any hook or script reading a top-level frontmatter key (e.g. type:) silently sees nothing — the value moved to metadata.type. In our setup this broke a memory-routing pipeline: files written with top-level type: failed classification because the router reads top-level only, and silently piled up in an _unrouted/ directory.
  • The #-truncation is data loss — issue/PR references (#762), or any # in a description, are destroyed. Surprising, since the rest of the description is preserved.
  • The rewrite is silent: no diff, no notice; the tool reports success with the content the user supplied, while a different thing lands on disk.

Notes

  • Only fires for .md files under the recognized memory directory; files elsewhere are untouched.
  • Happens inside the Write/Edit tool body, before the file is written — it is not a PostToolUse hook and cannot be disabled via ~/.claude/settings.json.
  • The #-truncation is a YAML-serialization side effect: the rewritten description is emitted unquoted, so # starts a comment. Quoting string values on re-serialization would fix that effect.

Suggested fix

A way to preserve frontmatter as authored — either:

  • preserve top-level keys (don't relocate them under metadata:), or a setting to opt out of the memory-file frontmatter normalization; and
  • always quote string values when re-serializing, so # (and :) in description/name survive.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗