~/.tweakcc/system-prompts/data-claude-api-reference-csharp.md contains 66 occurrences of the two-character text \" and zero bare " characters:
…`Betas = [\"code-execution-2025-08-25\", \"skills-2025-10-02\"]`…
Those backslashes are JavaScript string-literal syntax from the bundle. They are not part of the prompt. Sync copies them into the markdown instead of decoding them, so anyone opening that file to customise it sees escape syntax rather than the text Claude Code actually receives.
28 of the 610 files generated for Claude Code 2.1.220 are affected.
The same decode gap shows up in a smaller variant: skill-artifact-whiteboard.md and skill-artifact-data-table.md carry literal \uXXXX text for the same reason. A fix should cover both spellings rather than quotes alone.
What it does on the way back
Because the markdown holds \" as content, the backslash-preserving pass from #664 doubles it, and the quote-escaping pass then escapes the quote:
vanilla : `Betas = [\"code-execution-2025-08-25\", …
patched : `Betas = [\\\"code-execution-2025-08-25\\\", …
Measured inside that one prompt: \" 66 to 0, \\" 0 to 66. Claude Code ends up reading \" where the bundle originally had ".
The output is valid JavaScript, so node --check, boot and -p all pass. #908's parse-gate cannot see it.
Relationship to #660
#660 reported data-http-error-codes-reference and skill-stuck-slash-command breaking JS through literal \' in their content, and was closed. Both of those files are still in the affected set here.
What changed is the symptom, not the cause. #664 began doubling backslashes for " and ' delimiters, which turns the previously-invalid escape into valid JavaScript. The crash went away. The spurious backslash did not.
So this is the same root cause #660 was pointing at, still live, now silent instead of loud.
Why it is separate from the \uXXXX issue
There is a related defect where --apply corrupts \uXXXX escapes, filed as #920. The two look identical in a diff and are not the same bug:
|
#920 |
this issue |
| markdown contains |
the real character (em dash) |
the escape text \" |
| introduced by |
apply, after sync was correct |
sync, when writing the .md |
| fix location |
src/patches/systemPrompts.ts |
markdown generation in src/systemPromptSync.ts |
The discriminator is just reading the generated .md: a real character means apply broke it, escape text means sync never decoded it. Fixing #920 leaves these 28 files wrong.
Reproducing
node dist/index.mjs --apply -y
cd ~/.tweakcc/system-prompts
# escape text where the prompt should just have a quote
grep -oP '(?<!\\)\\"' data-claude-api-reference-csharp.md | wc -l # 66
grep -oP '(?<!\\)"' data-claude-api-reference-csharp.md | wc -l # 0
# how many generated files carry undecoded quote escapes
grep -lP '(?<!\\)\\"' *.md | wc -l # 28
grep -P is needed for the lookbehind; grep -c would count lines rather than occurrences.
Suggested direction
Decode JavaScript string escapes when generating the markdown, so the file holds " and the user edits the text Claude Code actually sees.
The constraint to respect: buildSearchRegexFromPieces matches literal, \uXXXX and \xHH spellings when searching the bundle, and the stored pieces must keep their raw escapes for that to work. Only the markdown rendering should decode. Round-tripping an unedited prompt must stay byte-identical, which is the natural gate for this change.
Environment
- tweakcc
48ac856 (markdown generation has no decode step in released v4.3.2 either)
- Claude Code 2.1.220, native Linux install
- Node 24
~/.tweakcc/system-prompts/data-claude-api-reference-csharp.mdcontains 66 occurrences of the two-character text\"and zero bare"characters:Those backslashes are JavaScript string-literal syntax from the bundle. They are not part of the prompt. Sync copies them into the markdown instead of decoding them, so anyone opening that file to customise it sees escape syntax rather than the text Claude Code actually receives.
28 of the 610 files generated for Claude Code 2.1.220 are affected.
The same decode gap shows up in a smaller variant:
skill-artifact-whiteboard.mdandskill-artifact-data-table.mdcarry literal\uXXXXtext for the same reason. A fix should cover both spellings rather than quotes alone.What it does on the way back
Because the markdown holds
\"as content, the backslash-preserving pass from #664 doubles it, and the quote-escaping pass then escapes the quote:Measured inside that one prompt:
\"66 to 0,\\"0 to 66. Claude Code ends up reading\"where the bundle originally had".The output is valid JavaScript, so
node --check, boot and-pall pass. #908's parse-gate cannot see it.Relationship to #660
#660 reported
data-http-error-codes-referenceandskill-stuck-slash-commandbreaking JS through literal\'in their content, and was closed. Both of those files are still in the affected set here.What changed is the symptom, not the cause. #664 began doubling backslashes for
"and'delimiters, which turns the previously-invalid escape into valid JavaScript. The crash went away. The spurious backslash did not.So this is the same root cause #660 was pointing at, still live, now silent instead of loud.
Why it is separate from the
\uXXXXissueThere is a related defect where
--applycorrupts\uXXXXescapes, filed as #920. The two look identical in a diff and are not the same bug:\".mdsrc/patches/systemPrompts.tssrc/systemPromptSync.tsThe discriminator is just reading the generated
.md: a real character means apply broke it, escape text means sync never decoded it. Fixing #920 leaves these 28 files wrong.Reproducing
grep -Pis needed for the lookbehind;grep -cwould count lines rather than occurrences.Suggested direction
Decode JavaScript string escapes when generating the markdown, so the file holds
"and the user edits the text Claude Code actually sees.The constraint to respect:
buildSearchRegexFromPiecesmatches literal,\uXXXXand\xHHspellings when searching the bundle, and the storedpiecesmust keep their raw escapes for that to work. Only the markdown rendering should decode. Round-tripping an unedited prompt must stay byte-identical, which is the natural gate for this change.Environment
48ac856(markdown generation has no decode step in released v4.3.2 either)