# Edit Tool Unicode Failure

> Fix for Claude Code Edit tool failing to match strings containing Unicode characters (emojis, em-dashes, non-breaking spaces, curly quotes). Use when: (1) Edit tool returns "String to replace not found in file" but the string visually matches Read output, (2) file contains emoji characters like 🚀 👋 🎮, (3) file has em-dashes (—), non-breaking spaces (U+00A0 / c2 a0), or smart/curly quotes. Solution: use Write tool to rewrite the entire file instead of Edit for targeted replacements.

- Skill: `hubeiqiao/edit-tool-unicode-failure` (Agent Skill)
- Install (CLI): `npx skillmds@latest add hubeiqiao/edit-tool-unicode-failure`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hubeiqiao/edit-tool-unicode-failure/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: hubeiqiao (https://skillmd.com/u/hubeiqiao)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hubeiqiao/edit-tool-unicode-failure

---


# 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_string` visually 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)
1. Read the full file with the Read tool
2. Understand the complete content
3. Use the Write tool to rewrite the entire file with your changes
4. This bypasses the string matching entirely

### Option 2: Match on ASCII-only substrings
1. Find a unique ASCII-only substring near your target
2. Use Edit with that smaller, ASCII-only `old_string`
3. Include enough surrounding ASCII context for uniqueness

### Option 3: Diagnose with xxd
If unsure whether Unicode is the issue:
```bash
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

