Skip to content

System-prompt sync aborts on prompts whose content starts with an HTML comment, leaving later prompts uncreated (ENOENT on --apply) #888

Description

@StreamDemon

Summary

Running --apply prints a batch of Failed to read markdown file ... ENOENT errors for a set of system prompts, e.g.:

Failed to read markdown file ~/.tweakcc/system-prompts/tool-description-sendfile.md: Error: ENOENT: no such file or directory ...

On Claude Code 2.1.212 this is 14 prompts (the ones added in recent versions: memory, code-review, artifacts, cloud-agent, browser navigate, sendfile, etc.). The errors are non-fatal (the prompts are skipped), but those system prompts are then silently never customizable or applied.

Root cause

generateMarkdownFromPrompt and updateVariables in src/systemPromptSync.ts build each prompt's markdown with:

matter.stringify(content, frontmatterData, { delimiters: ['<!--', '-->'] })

gray-matter's matter.stringify re-parses a string argument as front matter first:

matter.stringify = function(file, data, options) {
  if (typeof file === 'string') file = matter(file, options); // <-- re-parse
  return stringify(file, data, options);
};

tweakcc uses <!--/--> as its front-matter delimiters, so a prompt whose content itself begins with <!-- (an HTML template such as data-plan-artifact-html-template, whose body starts with an HTML comment on Claude Code 2.1.208+) collides with the delimiters. gray-matter hands the enclosed prose to js-yaml, which throws:

YAMLException: bad indentation of a mapping entry

syncSystemPrompts rethrows on any prompt failure, so that single throw aborts the whole sync. Every prompt ordered after the offending one never gets its .md written, and the startup try/catch swallows the error. On the next --apply those files are missing, which is the ENOENT batch above.

(When the mis-parsed YAML happens to be valid, the body is silently corrupted instead of throwing: the content's leading comment is absorbed into the front matter and re-serialized.)

Reproduce

  1. Claude Code 2.1.208 or later installed
  2. Run tweakcc so the system-prompt sync runs (or --apply)
  3. The sync aborts at data-plan-artifact-html-template; the prompts ordered after it are left without .md files
  4. --apply prints Failed to read markdown file ... ENOENT for each

Fix

Pass the content as a file object ({ content }) at both call sites so gray-matter skips the string re-parse and stringifies the body verbatim. Output is byte-identical for content that does not begin with <!--.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions