[FEATURE] Hash-based line addressing for the Edit tool (hashline approach)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
The current str_replace Edit tool requires the model to reproduce the exact old text character-by-character, including whitespace and indentation. This is a mechanical challenge, not an intellectual one — and it's where most edit failures originate.
Evidence from this repository:
- #164 — CRLF/LF line ending mismatches cause "string not found"
- #372 — Edit tool fails after reformatting
- #968 — "String to replace not found in file" (Go ecosystem, auto-formatting)
- #2107 — Same error on Windows
- #3471 — "Too many edit file errors" (open, 140+ reactions)
- #3513 — "File has been modified since read" persistent errors
- #9163, #13152, #11447, #18050 — Tab-indented files cannot be edited at all
- #15290 — 15 consecutive failed edit attempts due to backslash escape sequences
- #3309 — Unhandled crash on string mismatch instead of graceful error
Root cause analysis (5 Whys):
- Why do edits fail? → old_string doesn't match file content
- Why doesn't it match? → Whitespace/tabs/escapes differ from what the model outputs
- Why does the model output wrong whitespace? → It must reproduce text byte-for-byte from memory
- Why must it reproduce text? → The Edit tool uses exact string matching as its addressing mechanism
- Why use exact string matching? → This is a design choice, not a requirement
Recent research ("The Harness Problem" by Can Bölük, Feb 2026) demonstrated that changing only the edit tool — without modifying the model or prompt — improved 15 different LLMs by 5-14 percentage points on coding benchmarks. The weakest models gained up to 10x improvement. Output tokens dropped ~20% because models stopped burning tokens on retry loops.
The problem isn't the model's intelligence. It's the edit tool's interface design.
Proposed Solution
Implement hash-based line addressing as an alternative edit mode for the Edit tool. Instead of requiring exact text reproduction, each line gets a short content hash computed on read:
1:a3|function hello() {
2:f1| return "world";
3:0e|}
The model then references lines by hash: "replace line 2:f1" or "replace range 1:a3 through 3:0e" — without reproducing the old content.
Key properties:
- Hash is whitespace-insensitive — tabs vs spaces, reformatting, trailing whitespace no longer cause failures (fixes #164, #9163, #11447, #13152, #18050)
- Integrity verification — if the file changed since last read, the hash won't match and the edit is rejected before corruption occurs (fixes #3513)
- No old text reproduction — the model says "where" and "what", separately. Reduces output tokens by ~20%
- Graceful error recovery — on hash mismatch, show updated hashes with
>>>markers so the model can retry with correct references (fixes #3309)
Implementation options (from least to most invasive):
Option A: New edit mode flag
Add an optional addressing: "hashline" parameter to the existing Edit tool. When enabled, Read tool output includes line hashes. Edit tool accepts hash-based references. Fully backward-compatible.
Option B: Enhanced Read + Edit
Read tool always includes line hashes (as metadata, not changing the format for the model unless requested). Edit tool accepts both old_string (current) and line_ref (hash-based) parameters. Model chooses the more reliable method.
Option C: Built-in fuzzy fallback
Keep str_replace as primary, but add automatic fuzzy matching when exact match fails:
- Tier 1: Exact match (current behavior)
- Tier 2: Whitespace-insensitive match
- Tier 3: Indentation-preserving match
- Tier 4: Levenshtein distance match (threshold-based)
This is how Aider handles it and it already improves success rates by 10-30%.
Alternative Solutions
1. MCP server workaround (current)
Users can install third-party MCP servers like mcp-hashline-edit-server or mcp-text-editor that provide alternative edit tools. However, this creates a "two tools" problem — the model must be explicitly instructed (via CLAUDE.md) to prefer MCP tools over built-in ones, which is fragile and breaks when instructions are not present.
2. Cursor's approach (Neural Merge)
Train a separate model specifically for applying edits. This works but doubles inference costs and adds a second failure point. As noted by Paul Gauthier (Aider founder): "success depends on two LLMs not goofing up instead of one."
3. Full file rewrite
For files under ~400 lines, rewriting the entire file is more reliable than patching. Claude Code could auto-detect when str_replace fails and fall back to Write tool. But this wastes tokens for small edits in large files.
Priority
High - Significant impact on productivity
Feature Category
File operations
Use Case Example
Example scenario:
- I'm building a pipeline of 100+ Claude Code skills that automatically create, edit, and review project documents and code
- Skills use Edit tool extensively — creating markdown documents, modifying YAML configs, updating code files
- Approximately 15-20% of edit operations fail with "String to replace not found" on first attempt, requiring retry loops
- Tab-indented files (Go, Makefiles) are essentially uneditable (#9163, #11447)
- After auto-formatting (Prettier, Black, gofmt), subsequent edits fail because the model's cached content no longer matches the reformatted file
- With hash-based addressing, the model would reference
line 42:f1instead of reproducing 3 lines of exact whitespace — eliminating the entire class of whitespace-related failures - This would save ~20% output tokens across thousands of daily edit operations
Additional Context
Research:
- "The Harness Problem" — Can Bölük (Feb 2026). Benchmarked 16 models × 180 tasks × 3 runs. Hashline matched or beat str_replace for every model tested.
- "Code Surgery: How AI Assistants Make Precise Edits" — Fabian Hertwig. Comparative analysis of 5 edit systems (Codex, Aider, OpenHands, RooCode, Cursor).
- "The Importance of Agent Harness" — Philipp Schmid (HuggingFace). Argues for lightweight, adaptable harness infrastructure.
- Aider edit format benchmarks — format choice alone swung GPT-4 Turbo from 26% to 59%.
Existing implementations:
- mcp-hashline-edit-server — MCP server implementing hashline (requires Bun + ripgrep)
- mcp-text-editor — Line-based editing with file-hash conflict detection (Python, 181 stars)
- editor-mcp — Multi-step editing workflow with diff preview and syntax validation
Convergent industry principles (from Hertwig's analysis):
All successful edit systems converge on: (1) avoid relying on exact text reproduction, (2) layered matching with fuzzy fallbacks, (3) actionable error messages, (4) whitespace-resilient addressing.
Claude Code's Edit tool currently implements none of these.
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗