edit-tool-unicode-failure
Installation
SKILL.md
Edit Tool Unicode Failure Workaround
Problem
The Edit tool's old_string parameter fails to match text containing Unicode characters,
even when the string appears identical in Read tool output. This causes silent failures
with the error "String to replace not found in file."
Context / Trigger Conditions
- Edit tool returns "String to replace not found in file"
- The
old_stringvisually matches what Read tool shows - File contains any of these Unicode characters:
- Emojis: š š š® šŗ š etc. (multi-byte UTF-8 sequences, 4 bytes each)
- Em-dashes: ā (U+2014, bytes
e2 80 94) - Non-breaking spaces: (U+00A0, bytes
c2 a0) ā invisible, looks like regular space - Curly/smart quotes: '' "" (U+2018/2019/201C/201D)
- Other multi-byte Unicode: flags šØš¦, variation selectors āļø
Solution
Option 1: Write the entire file (recommended for files with many Unicode chars)
- Read the full file with the Read tool
- Understand the complete content
- Use the Write tool to rewrite the entire file with your changes
- This bypasses the string matching entirely
Option 2: Match on ASCII-only substrings
- Find a unique ASCII-only substring near your target
- Use Edit with that smaller, ASCII-only
old_string - Include enough surrounding ASCII context for uniqueness
Option 3: Diagnose with xxd
If unsure whether Unicode is the issue:
sed -n 'Np' /path/to/file | xxd | head -10
Look for multi-byte sequences: f0 9f (emoji), e2 80 94 (em-dash), c2 a0 (NBSP)
Verification
After using Write, re-read the file to confirm changes applied correctly and no content was lost.
Example
Failing approach:
Edit old_string="Moved from Beijing ā freely doing what I love šāļøš"
ā ERROR: String to replace not found
Working approach:
Read the full file ā Write the entire file with modifications
Notes
- The Read tool displays Unicode correctly, but the bytes don't round-trip through Edit's matching
- This issue is especially common in JSX/TSX files with emoji content, markdown files, and i18n strings
- When rewriting with Write, preserve all original content exactly ā don't accidentally drop imports, exports, or other sections
- If the file is very large (500+ lines), try Option 2 first to avoid rewriting everything
- Non-breaking spaces (U+00A0) are particularly insidious because they're invisible ā use xxd to detect them