claude-code - 💡(How to fix) Fix Edit tool: show diff when 'String to replace not found' fails

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
RAW_BUFFERClick to expand / collapse

Problem

When the Edit tool can't find old_string in the file, it returns:

String to replace not found in file

This gives no information about why the match failed. In practice, the cause is almost always invisible whitespace differences — trailing spaces, tabs vs spaces, CRLF vs LF, or formatting drift from auto-save/linters.

Suggested Fix

When the match fails, show the closest near-match from the file with differences highlighted. For example:

String to replace not found. Closest match at line 42:

  • Expected: def foo(self): (4 spaces)
  • Found: \tdef foo(self): (1 tab)

Even a simple "did you mean line X?" with the actual content would help. The user currently has to re-read the file and visually diff to find what changed.

Impact

Minor but frequent UX pain point. Especially affects projects where formatters normalize whitespace between Read and Edit calls. Related to the linter race condition issue (#51361) but distinct — this also happens when the user manually constructs an old_string with incorrect whitespace.

Environment

  • Claude Code CLI on Windows 11
  • Projects with mixed formatting tools (Black, Prettier, EditorConfig)

extent analysis

TL;DR

Modify the Edit tool to display the closest near-match from the file with differences highlighted when the old_string is not found.

Guidance

  • Identify the cause of the match failure by comparing the expected old_string with the actual content of the file, focusing on invisible whitespace differences.
  • Implement a diff-like feature to highlight the differences between the expected and actual strings, such as trailing spaces, tabs vs spaces, or CRLF vs LF.
  • Consider displaying a simple "did you mean line X?" message with the actual content to help the user locate the closest match.
  • Review the formatting tools used in the project (Black, Prettier, EditorConfig) to ensure consistent whitespace normalization.

Example

def find_closest_match(old_string, file_content):
    # Split the file content into lines
    lines = file_content.splitlines()
    
    # Initialize the closest match and its distance
    closest_match = None
    min_distance = float('inf')
    
    # Iterate over the lines to find the closest match
    for i, line in enumerate(lines):
        # Calculate the Levenshtein distance between the old_string and the current line
        distance = levenshtein_distance(old_string, line)
        
        # Update the closest match if the distance is smaller
        if distance < min_distance:
            min_distance = distance
            closest_match = (i, line)
    
    return closest_match

def levenshtein_distance(s1, s2):
    # Calculate the Levenshtein distance between two strings
    # ...

Notes

This solution assumes that the Edit tool has access to the file content and can perform string comparisons. The implementation of the diff-like feature and the Levenshtein distance calculation may vary depending on the programming language and the specific requirements of the project.

Recommendation

Apply a workaround by modifying the Edit tool to display the closest near-match with differences highlighted, as this will provide a better user experience and help identify the cause of the match failure.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Edit tool: show diff when 'String to replace not found' fails