[FEATURE] Hash-based line addressing for the Edit tool (hashline approach)

Resolved 💬 7 comments Opened Feb 14, 2026 by levnikolaevich Closed Mar 15, 2026

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):

  1. Why do edits fail? → old_string doesn't match file content
  2. Why doesn't it match? → Whitespace/tabs/escapes differ from what the model outputs
  3. Why does the model output wrong whitespace? → It must reproduce text byte-for-byte from memory
  4. Why must it reproduce text? → The Edit tool uses exact string matching as its addressing mechanism
  5. 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:

  1. Hash is whitespace-insensitive — tabs vs spaces, reformatting, trailing whitespace no longer cause failures (fixes #164, #9163, #11447, #13152, #18050)
  2. Integrity verification — if the file changed since last read, the hash won't match and the edit is rejected before corruption occurs (fixes #3513)
  3. No old text reproduction — the model says "where" and "what", separately. Reduces output tokens by ~20%
  4. 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:

  1. I'm building a pipeline of 100+ Claude Code skills that automatically create, edit, and review project documents and code
  2. Skills use Edit tool extensively — creating markdown documents, modifying YAML configs, updating code files
  3. Approximately 15-20% of edit operations fail with "String to replace not found" on first attempt, requiring retry loops
  4. Tab-indented files (Go, Makefiles) are essentially uneditable (#9163, #11447)
  5. After auto-formatting (Prettier, Black, gofmt), subsequent edits fail because the model's cached content no longer matches the reformatted file
  6. With hash-based addressing, the model would reference line 42:f1 instead of reproducing 3 lines of exact whitespace — eliminating the entire class of whitespace-related failures
  7. This would save ~20% output tokens across thousands of daily edit operations

Additional Context

Research:

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.

View original on GitHub ↗

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