Skip to content

[FEATURE]: Make fuzzy edit feedback stricter to improve SWE-bench reliability #34424

Closed

Description

@yaoyi1222

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

I would like OpenCode's native edit tool to expose stricter and more explicit feedback when it uses fuzzy/loose fallback matching.

In our SWE-bench Pro experiment, OpenCode's native edit arm had the lowest resolved score under pass@5. The pattern we observed was not that edits failed visibly. Instead, fuzzy edits often returned local success, and the model then treated that local success as evidence that a larger multi-file change was complete.

Research repo and result tables:
https://github.com/yaoyi1222/edit-tool-bench

Suggested improvements:

  1. Make loose/fuzzy fallback opt-in, or provide a stricter agent/benchmark mode.
  2. Distinguish exact edit success from fuzzy fallback success in tool output.
  3. Report changed line ranges and match/fallback strategy.
  4. Treat broad fallback matches as warnings instead of plain success.
  5. Make patch-style editing available consistently, not only through model-conditional tool substitution.

Strongly related issues:

The issue is not only mechanical file corruption. The design problem is that fuzzy edit success becomes part of the agent's reasoning loop. If the tool reports success too optimistically, the model may stop investigating before the full public/API/test contract is preserved.

Activity

  1. github-actions commented on Jun 29, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • No issue template was used. Please resubmit using one of the three required templates: Bug Report, Feature Request, or Question. Each template has required fields that must be filled in.
    • The current format (custom research report with experiment tables and detailed case studies) does not match any of the accepted templates.

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. github-actions commented on Jun 29, 2026

    @github-actions
    Contributor

    Thanks for updating this issue and switching to the Feature Request template — the description and checkbox look great.

    One remaining item to fix:

    • Title must start with [FEATURE]: — Feature requests require the title to begin with [FEATURE]:. Please edit the title to something like: [FEATURE]: Native fuzzy edit reduce SWE-bench reliability

    Once that's done, the issue will be fully compliant.

  3. changed the title [-]Native fuzzy edit reduce SWE-bench reliability[/-] [+][FEATURE]: Make fuzzy edit feedback stricter to improve SWE-bench reliability[/+] on Jun 29, 2026
  4. github-actions commented on Jun 29, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows the contributing guidelines and feature request template. The needs:compliance label has been removed.

  5. polkamu-ops commented on Aug 25, 2026

    @polkamu-ops

    Coming from #44999 (which I'll close as overlapping with points 2/3 here). Contributing empirical + implementation-level findings that may help move this forward.

    Empirical probes (opencode 1.18.21, Windows) — which replacer absorbs which whitespace drift:

    File content oldString Result Matched via
    beta_line (3sp) beta_line (4sp) applied LineTrimmedReplacer
    foo bar (2sp) foo bar (1sp) applied WhitespaceNormalizedReplacer
    tab-indented line 4-space indent applied LineTrimmedReplacer
    control nonexistent text rejected —

    So a fuzzy hit returns the exact same "Edit applied successfully." as a byte-exact match — callers cannot distinguish the two. Real-world case: in a spec-driven refactor, a spec's oldString carried 4-space indentation while the file had 3; the edit silently rewrote the line with the wrong indentation, caught only by manual base-branch diff review.

    Source-level cause (packages/opencode/src/tool/edit.ts): replace() walks the nine-replacer chain (SimpleReplacer first) and knows which replacer matched, but returns only the replaced string — the strategy is discarded at return. The tool output is the constant "Edit applied successfully.", and ctx.metadata carries only diff/filediff/diagnostics.

    Minimal implementation sketch for points 2/3 (zero signature change): SimpleReplacer is first in the chain and yields oldString verbatim, so exact-match-won ⇔ contentOld.includes(old) (ambiguous multi-match inputs throw before returning). In execute, after a successful replacement:

    const wasExact = contentOld.includes(old)
    let output = "Edit applied successfully."
    if (!wasExact)
      output += `\nNote: oldString did not match byte-for-byte; applied via fuzzy fallback. Verify the region if unintended.`
    // + matchStrategy: wasExact ? "exact" : "fuzzy" into ctx.metadata

    This delivers points 2/3 in minimal non-breaking form; point 1 can layer on as an exact: true parameter restricting the chain to SimpleReplacer. Related: #44996 (the not-found error text claims exact whitespace matching, contradicting this same behavior).

  6. neriousy commented on Oct 22, 2026

    @neriousy
    Member

    Partly done: V2's edit tool replaced the V1 chain of nine fuzzy replacers. It now tries an exact match, then typographic normalization, then trailing whitespace only, with no indentation or whitespace-collapsing fuzzy matching (packages/core/src/tool/plugin/edit.ts). The output still doesn't say whether a match was normalized and doesn't report changed line ranges; #45491 was closed unmerged. Closing this, since the main cause of loose matches is gone.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions