[BUG] Edit tool fails silently when file contains non-breaking spaces (U+00A0)

Resolved 💬 2 comments Opened Mar 1, 2026 by MatthiasRossbach Closed Mar 4, 2026

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 0x20c2 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

  1. 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
``

  1. Use the Read tool to read the file — the non-breaking space appears as a regular space
  2. Use the Edit tool to replace text on that line, using the exact string shown by Read
  3. Edit fails: "String to replace not found in file"
  4. The only workaround is hexdump to 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

View original on GitHub ↗

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