[BUG] Edit tool fails silently when file contains non-breaking spaces (U+00A0)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The Edit tool fails with "String to replace not found in file" when the target file contains non-breaking spaces (U+00A0, UTF-8 c2 a0). The Read tool renders them identically to regular spaces, so the model generates old_string with ASCII spaces (0x20). The Edit tool does strict byte matching, so 0x20 ≠ c2 a0 = silent failure.
This is extremely hard to diagnose because the text looks correct in every tool output.
What Should Happen?
The Edit tool should either:
- Normalize Unicode whitespace (U+00A0, U+2007, U+202F, etc.) to ASCII space during matching, or
- The Read tool should visually flag/annotate non-ASCII whitespace so the model can account for it
Error Messages/Logs
The file /path/to/file.md has been updated successfully. ← first Edit works, triggers linter
File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.
String to replace not found in file. ← re-read + retry fails on nbsp lines
Hex dump of affected line showing the invisible U+00A0:
6c 69 73 74 20 69 6e c2 a0 63 75 72 72 65 6e 74 |list in..current|
^^^^^
U+00A0 non-breaking space
Steps to Reproduce
- Create a markdown file containing a non-breaking space (e.g., copy-paste from Notion/Google Docs, or press Option+Space on macOS):
````
echo -e "update the task list in\xc2\xa0current-iteration.md" > test.md
- Use the Read tool to read the file — the non-breaking space appears as a regular space
- Use the Edit tool to replace text on that line, using the exact string shown by Read
- Edit fails: "String to replace not found in file"
- The only workaround is
hexdumpto identify the issue, then fall back to Python/Bash
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
2.1.63 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
Root cause: The Read tool and Edit tool have inconsistent handling of non-ASCII whitespace. Read renders U+00A0 as a visually identical regular space. The model then emits ASCII 0x20 in old_string. Edit does byte-exact matching and fails.
How common: Non-breaking spaces are silently introduced by:
- Copy-paste from rich text editors (Notion, Confluence, Google Docs)
- macOS Option+Space keystrokes
- Some AI-generated content
In our project, we found 287 non-breaking spaces across 8 markdown instruction files — none were intentional.
Related issues (same class of problem — invisible character mismatch between Read and Edit):
- #15920 — Edit tool corrupts/can't match Unicode typographic characters (e.g.,
'U+2019) - #9163 / #13152 — Edit tool can't match tab characters
- #18050 — Edit tool cannot match literal tab characters in old_string/new_string
- #29699 — Edit tool Unicode-to-ASCII mojibake on Windows
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗