Edit tool silently introduces Unicode curly quotes into source code
Summary
The Edit tool sometimes replaces straight ASCII quotes (' U+0027, " U+0022) with Unicode curly quotes (' U+2018, ' U+2019, " U+201C, " U+201D) when writing new_string content into files. This happens silently and causes hard-to-diagnose runtime bugs, because the corrupted characters are visually near-identical in most editors and terminal output.
Reproduction
Use the Edit tool to insert or replace code containing quote characters inside regex character classes or string literals in a .mjs file. For example, writing a new_string like:
if (/^["'(]+\s*the\s+/i.test(clean)) return false;
produces this in the file (confirmed via Python byte inspection):
/^[\xe2\x80\x9c\xe2\x80\x99(]+\s*the\s+/i.test(clean)
The " (U+0022) became \xe2\x80\x9c (U+201C, left double curly quote) and ' (U+0027) became \xe2\x80\x99 (U+2019, right single curly quote). The regex now matches curly quotes instead of straight quotes, so it silently fails to match any input containing straight quotes.
Impact
This is a silent data corruption bug. It does not produce any error or warning. The file parses and runs fine syntactically (JS allows Unicode in regex character classes). The only symptom is wrong runtime behaviour, which looks like a logic error in the user's code rather than a tooling issue.
In my case, I spent a significant chunk of a session debugging why a filter function was not rejecting known-bad input, eventually resorting to Python byte-level file inspection to discover the corrupted characters. The Edit tool had been called multiple times on the same function, and each call introduced more curly quotes into the regex patterns and string literals.
Observed pattern
- Happens when the
new_stringcontains'or"characters, particularly inside JS regex character classes like["'(]or string delimiters - Seems more likely when the surrounding text in
new_stringcontains English prose (e.g. comments), as if a smart-quote transformation is being applied to the entire string - The
old_stringmatching still works with straight quotes (so the edit applies), but the written output has curly quotes - Multiple Edit calls to the same region compound the problem, each potentially introducing more curly substitutions
- I have only observed this in
.mjsfiles but have no reason to think it is file-extension-specific
Environment
- macOS (Darwin 25.2.0)
- Claude Code CLI
- Model: claude-opus-4-6
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗