Edit tool silently introduces Unicode curly quotes into source code

Resolved 💬 4 comments Opened Mar 7, 2026 by paultendo Closed Apr 5, 2026

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_string contains ' or " characters, particularly inside JS regex character classes like ["'(] or string delimiters
  • Seems more likely when the surrounding text in new_string contains English prose (e.g. comments), as if a smart-quote transformation is being applied to the entire string
  • The old_string matching 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 .mjs files 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

View original on GitHub ↗

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