Repository navigation
Description
Description
Summary
The edit tool intermittently reports "Could not find oldString" for text that is verifiably present in the target file, and separately reports genuinely different oldString/newString pairs as identical when they differ only in leading whitespace. Both block file editing and force workarounds.
Environment
- opencode version: v2.0.16
- OS: Linux grimorio 6.8.0-142-generic (linux x86_64), Ubuntu 24.04
- Terminal: TERM=xterm-256color, COLORTERM=truecolor, TERM_PROGRAM unset
- Shell: /bin/bash
- Install/channel: latest
- Active plugins: none found in config
Reproduction
Three independent failures, all observed in a single session while editing Python and Markdown files.
1. Whitespace-only difference reported as identical
edit(
path="tests/test_cli.py",
oldString='rewrites nothing that was said."""',
newString=' rewrites nothing that was said."""',
)Expected: the 4 leading spaces inserted.
Actual:
Error: No changes to apply: oldString and newString are identical.
The two arguments are not identical. The tool appears to trim or otherwise normalize whitespace before comparing them, so a legitimate indentation-only edit is discarded.
2. oldString not found, byte-for-byte present
edit(
path="agenda.md",
oldString="## Not decided\n",
newString="## Not decided\n\n- **New item.** ...\n",
)grep -n "Not decided" agenda.md returned 48:## Not decided, and the line is exactly ## Not decided with no trailing content.
Actual:
Error: Could not find oldString in /home/marea/hub/acciughe/agenda.md.
Re-issuing the identical call with the trailing newline removed from oldString succeeded against the same file, unchanged.
3. Multi-line oldString ending in """ not found
edit(
path="src/acciughe/model.py",
oldString=' about again.\n """',
newString=' about again.\n\n The model is asked ...\n """',
)The target text was confirmed present by reading the file at the reported line numbers.
Actual:
Error: Could not find oldString in /home/marea/hub/acciughe/model.py.
The same edit succeeded after re-reading the file and re-anchoring the oldString on different, longer surrounding text.
Steps common to all three
- Read a file to locate the exact text.
- Call
editwith anoldStringtaken verbatim from that read. - Receive a mismatch error.
- Confirm with
readand/orgrepthat the text is present and unmodified. - Re-anchor on a longer or shorter span, or split the edit — it then succeeds against an unchanged file.
Expected Behavior
edit matches oldString against the file contents as given. When it cannot find it, the reported reason is accurate. When oldString and newString differ, the edit is applied.
Actual Behavior
- Case 1: a whitespace-only edit is rejected as a no-op.
- Cases 2 and 3: a verbatim
oldStringis reported absent from a file where it is present. Re-anchoring succeeds with no intervening change to the file.
Pattern worth investigating: failures 1 and 3 both involve """ in newString, and case 2 differs from its working variant only by a trailing \n. This suggests quote escaping and/or trailing-whitespace handling in the argument layer rather than a genuine mismatch.
Additional Context
- Frequency: intermittent, roughly 6 failures across ~150 tool calls in one session. Every failure was recoverable by re-reading the file and re-anchoring, but it reliably consumed an extra round trip and, in a long editing sequence, repeatedly stalled progress.
- Impact: highest on long edits where
oldStringis a full function or docstring block — exactly the case where a long anchor is worth using. The failure pushes the agent toward progressively shorter anchors, which is the opposite of what makes edits safe. - Workarounds tried, all of which helped: re-read the file immediately before retrying; shorten
oldStringto a smaller unique span; split one large edit into several small ones; anchor on text that avoids"""sequences. - Workarounds that were unavailable by policy: in-place
sed/perledits were ruled out in this project because they risk corrupting the working tree with no undo. The issue therefore has to be fixed upstream rather than worked around. - Related note: the agent documentation advises splitting long
oldStrings and re-reading between edits as a workaround for exactly this. That guidance exists because the tool fails, not because long anchors are wrong. - No stack trace or log output was produced; the failures surface only as tool error strings.
Activity
github-actions commentedon Sep 29, 2026
This issue might be a duplicate of existing issues. Please check:
editmatching and misleading not-found behavior.maxx-ukoo commentedon Oct 27, 2026
I have the same issue. Today I use glm-5 model with opencode 2.2.0.
Logs:
ulab commentedon Oct 28, 2026
This is annoying, because the models fall for it again and again and always have to think and decide on a workaround. This takes time and tokens which add up.
Apparently this happens because the edit tool uses fuzzy matching. I am new to this, but isn't an edit tool supposed to be precise?
opencodejr commentedon Oct 28, 2026
Thanks for the detailed report!
I checked the
edittool in v2.0.16. The "oldString and newString are identical" error comes from a plainoldString === newStringcheck on the raw arguments. Nothing is trimmed or normalised first, so that error only appears when the two strings actually reached the tool identical. The lookup also tries an exact match first, so text that is really present byte-for-byte should be found. Both point to the arguments being changed before the tool ran, most likely in the model's output or the provider's tool-call handling, rather than in the matcher. To check this, could you share:anthropic/claude-...,openrouter/...).You can reply here, or edit the issue. If you edit it, please also leave a comment saying you've updated it, so we know you're done.
Related issues, most closely related first:
oldStringreported as not found (v2.0.22), closed pointing to this issueCould not find oldStringerrors on Windows, closed pointing to this issueeditcan't match anoldStringthe model retyped with ASCII stand-ins for Unicode punctuationedit: not-found error claims exact whitespace matching, but matching normalizes whitespace #44996: (v1) the not-found error message misdescribing how matching worksopencodejr commentedon Oct 31, 2026
Closing this for now, since we haven't heard back. In v2.0.16 the
edittool compares the raw arguments exactly, so both errors suggest the arguments were changed before they reached the tool. To check that, we needed the provider and model, plus the tool-call input the tool actually received for one failing call.If it still happens, please reply with those details (a session export or the tool call's input as shown in the TUI works) and we can reopen. Thanks for the detailed write-up!