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

Resolved 💬 3 comments Opened Mar 1, 2026 by MatthiasRossbach Closed Mar 1, 2026

Description

The Edit tool fails to match old_string when the target file contains non-breaking spaces (U+00A0, UTF-8 bytes c2 a0). The model generates regular spaces (0x20) in the old_string parameter, but the file contains visually identical non-breaking spaces, causing a silent "String to replace not found" error.

Steps to Reproduce

  1. Have a markdown file containing non-breaking spaces (common when content was copy-pasted from rich text sources like Notion, Google Docs, or AI-generated output)
  2. Read the file with the Read tool — non-breaking spaces render identically to regular spaces
  3. Attempt to edit a line containing a non-breaking space using the Edit tool
  4. Edit fails with "String to replace not found in file"

Example

File content (hex dump of affected line):

68 65 20 74 61 73 6b 20 6c 69 73 74 20 69 6e c2 a0 63 75 72 72 65 6e 74
                                               ^^^^^ 
                                               U+00A0 non-breaking space

The Read tool displays this as: the task list in current
The model generates old_string with: the task list in current (using 0x20)
The Edit tool fails because 0x20c2 a0

Root Cause

The model has no way to distinguish non-breaking spaces from regular spaces in the Read tool output — they are visually identical. When it constructs the old_string for the Edit tool, it naturally uses regular ASCII spaces. The Edit tool performs strict byte-for-byte matching, so the mismatch causes a silent failure.

Impact

  • Hard to diagnose: The error message gives no hint about the whitespace mismatch. Users see "String to replace not found" for text that appears to match exactly.
  • Common source: Non-breaking spaces are silently introduced by copy-paste from rich text editors (Notion, Confluence, Google Docs), macOS Option+Space keystrokes, and some AI-generated content.
  • Workaround tax: The only workaround is to use hexdump to identify the issue, then fall back to Python/sed for the replacement — defeating the purpose of the Edit tool.

Suggested Fix

The Edit tool could normalize Unicode whitespace characters (U+00A0, U+2007, U+202F, etc.) to ASCII space (0x20) during string matching, while preserving the replacement behavior. Alternatively, the Read tool could annotate or flag non-ASCII whitespace characters.

Related Issues

This is the same class of problem as:

  • #15920 — Edit tool corrupts/can't match Unicode typographic characters (e.g., ' U+2019)
  • #9163 / #13152 — Edit tool can't match tab characters (Read displays as spaces, Edit expects literal tabs)
  • #18050 — Edit tool cannot match literal tab characters in old_string/new_string
  • #29699 — Edit tool Unicode-to-ASCII mojibake on Windows

All share the same root cause: the Read tool and Edit tool have inconsistent representations of special characters, and the model cannot bridge the gap.

Environment

  • Claude Code (CLI)
  • macOS Darwin 25.3.0
  • Files: Markdown (.md) instruction files in .claude/ directory

View original on GitHub ↗

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