Skip to content

fix(edit): show candidate lines with similarity score on oldText match failure #97035

Closed
maweibin wants to merge 1 commit into
openclaw:mainfrom
maweibin:fix/edit-tool-candidate-lines-97032
Closed

fix(edit): show candidate lines with similarity score on oldText match failure #97035
maweibin wants to merge 1 commit into
openclaw:mainfrom
maweibin:fix/edit-tool-candidate-lines-97032

Conversation

@maweibin

@maweibin maweibin commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #97032.

What Problem This Solves

When the edit tool's oldText match fails, it only returns "Could not find the exact text" with no diagnostic information. Users don't know whether the issue is wrong escaping, incorrect indentation, or whitespace mismatch — they can only guess and retry.

Why This Change Was Made

Extended getNotFoundError() to compute Levenshtein-based similarity scores between the oldText and file content lines. On match failure, the error now includes up to 3 nearest candidate lines with line numbers, similarity percentages, and a hint to check whitespace/indentation.

Inputs are capped (200 lines, 200 chars per line) to prevent unbounded CPU on large files. The matching algorithm itself is unchanged.

User Impact

Edit tool users now see actionable diagnostics on match failure:

Could not find the exact text in test.js.
  near line 2: "  console.log(\"Hello\");" (90% match, check whitespace/indentation)
  near line 1: "function hello() {" (30% match, check whitespace/indentation)

Evidence

Behavior addressed: Edit tool oldText match failure lacks candidate diagnostics.

Real environment tested: Node 24.13.1, direct applyEditsToNormalizedContent call.

Exact steps or command run after this patch:

node --import tsx -e "
import { applyEditsToNormalizedContent } from './src/agents/sessions/tools/edit-diff.js';
try {
  applyEditsToNormalizedContent(
    'function hello() {\n  console.log(\"Hello\");\n  return 42;\n}\n',
    [{ oldText: 'console.log(\"hello\")', newText: 'console.log(\"Hi\")' }],
    'test.js',
  );
} catch(e) { console.log(e.message); }
"

Evidence after fix:

$ node --import tsx -e "..."
Could not find the exact text in test.js. The old text must match exactly including all whitespace and newlines.
  near line 2: "  console.log(\"Hello\");" (90% match, check whitespace/indentation)
  near line 1: "function hello() {" (30% match, check whitespace/indentation)
$ node scripts/run-vitest.mjs src/agents/sessions/tools/edit.test.ts src/agents/agent-tools.create-openclaw-coding-tools.test.ts --run
  Test Files  2 passed (2)
  Tests      75 passed (75)

Observed result after fix: On oldText match failure, up to 3 nearest candidate lines are displayed with similarity scores. Whitespace/indentation differences are visible in the candidate output. Large files are bounded at 200 lines / 200 chars per line.

Regression Test Plan

  • node scripts/run-vitest.mjs src/agents/sessions/tools/edit.test.ts src/agents/agent-tools.create-openclaw-coding-tools.test.ts --run
    • Test Files 2 passed (2)
    • Tests 75 passed (75)
  • node scripts/run-oxlint.mjs src/agents/sessions/tools/edit-diff.ts — clean

AI Assistance

  • AI-assisted: Yes
  • Model used: Claude Opus 4.8 (1M context)
  • Co-Authored-By: Already in commit message

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Jun 26, 2026
@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 12:39 AM ET / 04:39 UTC.

Summary
The PR extends edit oldText mismatch errors with up to three Levenshtein-ranked candidate lines and adds focused regression tests.

PR surface: Source +58, Tests +106. Total +164 across 2 files.

Reproducibility: yes. Current main and v2026.6.11 are source-reproducible as generic edit mismatch errors with capped current-file context but no candidate-line diagnostics.

Review metrics: 1 noteworthy metric.

  • Open same-issue candidate PRs: 5 open candidate PRs including this one. Multiple live branches target the same edit-mismatch diagnostic issue, so maintainers should choose one user-facing output contract before merge.

Stored data model
Persistent data-model change detected: serialized state: src/agents/sessions/tools/edit-diff.ts, unknown-data-model-change: src/agents/sessions/tools/edit-diff.ts, unknown-data-model-change: src/agents/sessions/tools/edit.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #97032
Summary: This PR is one candidate fix for the canonical edit-tool oldText mismatch diagnostics issue, with several sibling PRs proposing different output contracts.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Refresh real behavior proof against c851eed with redacted terminal output or logs showing the edit mismatch diagnostic.
  • Have a maintainer choose whether this similarity-only format or a richer sibling format is canonical for the linked issue.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body includes terminal proof for the intended behavior, but it predates the latest force-push; the contributor should refresh current-head proof with redacted terminal output, logs, or a reproducible live transcript before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging this branch would choose a simpler similarity-score diagnostic while the linked issue asks for visible diff, indentation, and escaping markers and sibling PRs implement richer formats.
  • [P1] The durable PR proof has not been refreshed after the latest force-push, so contributor-owned current-head behavior proof is still needed before merge.

Maintainer options:

  1. Choose the canonical output before merge (recommended)
    Compare the candidate branches and update or select one branch to match the chosen bounded diagnostic contract before landing.
  2. Land this format intentionally
    Maintainers can accept the narrower similarity-score output after fresh proof and then close or rebase competing candidate PRs.
  3. Pause for a richer candidate
    If diff, indentation, and escaping markers are required, leave this PR open or close it only after a better canonical branch is selected.

Next step before merge

  • [P1] The remaining action is maintainer selection of the canonical diagnostic format plus contributor-owned current-head proof, not a safe automated code repair.

Maintainer decision needed

  • Question: Which oldText mismatch diagnostic format should become canonical for edit tool: show candidate lines with diff on oldText match failure #97032 before any candidate PR merges?
  • Rationale: The open candidate PRs expose different user-facing formats, and automation cannot choose whether similarity-only lines are enough or whether diff, indentation, and escaping hints are required.
  • Likely owner: vincentkoc — Recent edit-diff and adjacent edit-tool history make this the strongest routing signal for the output-contract choice.
  • Options:
    • Prefer richer bounded diagnostics (recommended): Choose or adapt a branch that keeps candidate search bounded while showing visible diff, indentation, and escaping hints closer to the linked issue request.
    • Accept similarity-only hints: After current-head proof, intentionally land this simpler format and ask sibling PRs to rebase or close against that contract.
    • Defer the feature: Keep the canonical issue open and pause candidate PRs if maintainers do not want to standardize extra diagnostic output now.

Security
Cleared: No concrete security or supply-chain concern was found; the diff changes edit-tool diagnostic formatting/tests and imports an existing internal helper.

Review details

Best possible solution:

Land one bounded edit-mismatch diagnostic contract that preserves exact matching and current-file context, then close or rebase sibling candidate PRs against that chosen contract.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main and v2026.6.11 are source-reproducible as generic edit mismatch errors with capped current-file context but no candidate-line diagnostics.

Is this the best way to solve the issue?

Unclear. The shared edit-diff path is the right layer, but this PR's similarity-only output is narrower than the linked issue and richer sibling PRs, so the final format needs maintainer selection.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f296dc4e68e4.

Label changes

Label justifications:

  • P3: This is a low-risk edit-tool ergonomics enhancement rather than an urgent regression or blocked runtime path.
  • merge-risk: 🚨 other: The concrete merge risk is product/UX contract drift from choosing one of several competing diagnostic formats for the same linked issue.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes terminal proof for the intended behavior, but it predates the latest force-push; the contributor should refresh current-head proof with redacted terminal output, logs, or a reproducible live transcript before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +58, Tests +106. Total +164 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 65 7 +58
Tests 1 106 0 +106
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 171 7 +164

What I checked:

Likely related people:

  • vincentkoc: Recent history shows an edit-diff/session-tool internals refactor and co-authorship on nearby edit no-op behavior, making this a strong owner signal for the diagnostic contract. (role: recent area contributor; confidence: high; commits: 0455028a3cd2, ab966c214be0; files: src/agents/sessions/tools/edit-diff.ts, src/agents/sessions/tools/edit.ts, src/agents/sessions/tools/edit.test.ts)
  • steipete: The large agent runtime internalization carried edit recovery into the current session edit-tool surface and touched the same owner area. (role: adjacent owner; confidence: high; commits: bb46b79d3c14; files: src/agents/sessions/tools/edit.ts, src/agents/sessions/tools/edit-diff.ts)
  • mikasa0818: Recently authored the merged unicode-safe mismatch hint truncation fix adjacent to this error-formatting path. (role: recent adjacent contributor; confidence: medium; commits: f27d494d00e7; files: src/agents/sessions/tools/edit.ts, src/agents/sessions/tools/edit.test.ts)
  • mbelinky: The earlier edit recovery hardening commit introduced the bounded current-file-content mismatch hint that this PR would extend. (role: introduced current mismatch-content behavior; confidence: medium; commits: 922f4e66ea1a; files: src/agents/pi-tools.host-edit.ts, src/agents/pi-tools.read.host-edit-recovery.test.ts, src/agents/pi-tools.read.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (3 earlier review cycles)
  • reviewed 2026-07-02T12:54:09.302Z sha 81a89e7 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-06T01:34:11.633Z sha 874f3d4 :: needs real behavior proof before merge. :: [P1] Move baseContent before using it
  • reviewed 2026-07-06T02:28:57.956Z sha c851eed :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jun 26, 2026
@maweibin
maweibin force-pushed the fix/edit-tool-candidate-lines-97032 branch from 70fc97a to 42829d2 Compare June 26, 2026 13:34
@clawsweeper clawsweeper Bot added status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 26, 2026
@maweibin

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jun 26, 2026
@maweibin
maweibin force-pushed the fix/edit-tool-candidate-lines-97032 branch from 42829d2 to cc916d2 Compare June 26, 2026 13:50
@maweibin

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@maweibin
maweibin force-pushed the fix/edit-tool-candidate-lines-97032 branch 2 times, most recently from d9bf83b to 69191be Compare June 26, 2026 13:53
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 26, 2026
@maweibin

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jun 26, 2026
@maweibin

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 2, 2026
@maweibin

maweibin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Merge Readiness

Edit tool UX improvement: when oldText match fails, the error now shows candidate lines ranked by Levenshtein similarity — users see where they likely made indentation/whitespace/escaping mistakes instead of guessing.

Check Status
Proof proof: sufficient + platinum hermit + ready for maintainer look
Scope edit-diff.ts (error formatting), edit.test.ts (5 new test cases)
Backward compat ✅ Error message format extended, not replaced
Tests ✅ all pass
CI ✅ green

@steipete @vincentkoc — UX polish on edit tool, ready for review.

maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
…dError (openclaw#97035 P2)

Use content.split('\n', CANDIDATE_MAX_LINES) instead of split on the
entire content then slice.  For large or minified files the old code
still traversed and allocated the whole file's line array before the
200-line cap applied.
maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
 P2)

oldText.split('\n') and line.trim() could scan oversized user/file
text before truncation caps applied.  Now both split and trim
operate on bounded input.
maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
@maweibin
maweibin force-pushed the fix/edit-tool-candidate-lines-97032 branch 2 times, most recently from 5d84b40 to 874f3d4 Compare July 6, 2026 01:07
maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
…dError (openclaw#97035 P2)

Use content.split('\n', CANDIDATE_MAX_LINES) instead of split on the
entire content then slice.  For large or minified files the old code
still traversed and allocated the whole file's line array before the
200-line cap applied.
maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
 P2)

oldText.split('\n') and line.trim() could scan oversized user/file
text before truncation caps applied.  Now both split and trim
operate on bounded input.
maweibin added a commit to maweibin/openclaw that referenced this pull request Jul 6, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 6, 2026
…h failure (openclaw#97035)

When oldText matching fails, the error message now shows up to 3
candidate lines from the file content ranked by similarity score
(Levenshtein distance), helping users identify whitespace or
indentation mismatches.

Bounds applied throughout:
- Content split capped at 200 lines
- Line scoring limited to first 200 chars per line
- oldText lines capped before trim/slicing
- similarityScore threshold at 0.3

Fixes: openclaw#97032
@maweibin
maweibin force-pushed the fix/edit-tool-candidate-lines-97032 branch from 874f3d4 to c851eed Compare July 6, 2026 02:07
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P2 Normal backlog priority with limited blast radius. labels Jul 6, 2026
@maweibin

maweibin commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@vincentkoc

Copy link
Copy Markdown
Member

Thanks @maweibin. The canonical fix for #97032 landed through #97038 as 4204a948457cafc601c1f27a1965fcfb011c2131.

We selected #97038 because it keeps the diagnostic in the shared edit-diff owner path, bounds both scan cost and output, and covers typo, indentation, escaping, cap, and surrogate-safe truncation behavior with focused tests. This PR targets the same behavior, so I’m closing it as superseded. Your parallel implementation helped validate the need and solution space.

@vincentkoc vincentkoc closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

edit tool: show candidate lines with diff on oldText match failure

2 participants