Skip to content

fix(tools): fuzzy edit can overwrite a block whose interior drifted #963

Description

@PierrunoYT

Version / branch / commit

Audited on main at 903e3d13 (2026-08-23).

Problem

edit_file promises that old_string must match byte-for-byte, but blockAnchorReplacer falls back to matching the first and last lines plus an average interior similarity threshold of 0.65. It then replaces the entire on-disk span even when the interior differs from old_string.

Reproduction

Given an on-disk block containing:

func a() {
	x := 1
	y := 2
	z := 3
	return
}

request an edit whose old_string is identical except for y := 99. The fuzzy matcher accepts the block and reports success, replacing the real y := 2 line even though the requested old content never existed.

Expected behavior

A drifted interior must make the edit fail or require an exact re-read/retry. The tool must not discard content that differs from old_string.

Actual behavior

The whole span is replaced and the tool reports Successfully edited (replaced 1 occurrence).

Relevant code

  • internal/tools/edit_replacers.go:30,154-249,466-481
  • internal/tools/edit_file.go:109-131

Suggested fix

Reject fuzzy block matches when any interior line materially differs from the requested old block. Add a regression test using the y := 2 / y := 99 drift case and prove it fails before the fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions