You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] apply_diff's ":start_line:" hint causes misleading failure when file has grown since line number was obtained #985
Describe the bug
When :start_line: is provided to apply_diff and the file has been modified (grown significantly) in the same session since the line number was obtained, the tool fails with a low similarity score error even though the SEARCH text is present verbatim in the file, just at a different line. The error message does not indicate that the text was found elsewhere in the file, making the failure misleading and hard to diagnose.
The bug mostly affects the "edit large Markdown docs" use case. Long Markdown files are more likely to trigger it because: (a) insertions are large (whole paragraphs), causing large line shifts; and (b) the agent is more likely to plan several diffs upfront using line numbers from a single initial read, rather than re-reading between each edit. In contrast, with code files edits are typically smaller (a few lines), shifts are minor, and the fuzzy window around :start_line: is usually wide enough to still find the match. In long Markdown with large block insertions, the shift can be hundreds of lines – well outside any reasonable fuzzy window.
To Reproduce
Create a file with N lines containing several section headings and no body content.
Have agent call apply_diff with :start_line:X pointing to heading A, and replace it with heading A + a large block of content. This succeeds and the file grows by M lines.
Have agent call apply_diff again with :start_line:X+M_old pointing to heading B (where X+M_old was the correct line before step 2, but is now stale). The SEARCH text is the exact text of heading B, present verbatim in the file.
Observe: the tool reports a low similarity score (e.g. 31%) and fails, even though the SEARCH text exists exactly in the file.
Expected behavior
Honestly, no idea; the issue seems to be on the design/requirements level of the tool. Could be: When :start_line: is provided but the SEARCH text is not found near that line, the tool should fall back to a full-file search and find the exact match elsewhere, then succeed (or at minimum warn that the match was found at a different line).
What version of zoo are you running
Version: 3.70.0 (ce7f7dc)
Additional context
Add any other context about the problem here.
Accounting for issue #868 together with this one, the following section in AGENTS.md has been helping the agent work around the issues relatively reliably.
Important notes on apply_diff
This section applies to modes that provide access to the apply_diff tool.
Substrings in SEARCH are not supported
The SEARCH block in apply_diff matches against complete lines only. Substring (partial-line) matching is not supported: if the SEARCH content does not span the full text of every line it touches, the match will fail with a low similarity score even if the substring is unambiguously present.
This is especially important for Markdown files, where paragraphs are commonly stored as single long lines (e.g. in Obsidian vaults, meeting transcripts, or any "hard-wrap off" editor). When editing such files, the SEARCH block for a paragraph line must contain the entire line, however long it is.
Before using apply_diff on a long line, use read_file to retrieve the exact full-line content, then copy the complete line verbatim into the SEARCH block.
Avoid :start_line: unless necessary for correctness
The :start_line: hint is based on a line number obtained at read time. Large sequential insertions into the same file cause large line shifts that quickly make any stored line number stale. A stale :start_line: causes apply_diff to search near the wrong location and fail with a low similarity score, even when the SEARCH text is present verbatim elsewhere in the file.
Employ :start_line: only if the apply_diff command with a specific SEARCH block would otherwise be ambiguous (multiple instances of SEARCH text in the file). In other cases, omit :start_line:.
- The ':start_line:[line_number]' header is strongly recommended for accurate matching. When provided, it must follow the exact syntax ':start_line:[integer]' (for example: ':start_line:220'). Do not write headers with shorthand forms like ':220' or variations like ':start_line=220'.
Adding in system prompt to never use start line fixes the tool call failures.
Looked into picking this up, but open PR #641 rewrites the exact :start_line: sentence this issue targets — changing "strongly recommended" to "required" — which is the opposite direction from the softening proposed here ("omit unless ambiguous"). Opening a PR from current main would both textually conflict with #641 and produce self-contradictory guidance.
Holding off until #641's fate is decided: if it merges, the right fix becomes rewording its new "required" sentence (stale-hint failure mode: the search is bounded to a window around :start_line:, including the line-number-stripping fallback, so a shifted hint fails even when the SEARCH text exists verbatim elsewhere); if it stalls/closes, this issue's original 2-line plan applies cleanly.
Claiming — addressed in #2248 (stale :start_line: bounded-fail now retries the full file, gated on a unique fuzzy match above the configured threshold; ambiguous targets get a precise error instead of a guessed edit).
Activity
lowlight-ua commentedon Jul 21, 2026
Accounting for issue #868 together with this one, the following section in
AGENTS.mdhas been helping the agent work around the issues relatively reliably.navroop005 commentedon Aug 18, 2026
This line should be removed from description to avoid this issue. Or also add an example without start_line.
Zoo-Code/src/core/prompts/tools/native-tools/apply_diff.ts
Line 15 in 3e8144a
Adding in system prompt to never use start line fixes the tool call failures.
myk1yt commentedon Sep 20, 2026
Looked into picking this up, but open PR #641 rewrites the exact
:start_line:sentence this issue targets — changing "strongly recommended" to "required" — which is the opposite direction from the softening proposed here ("omit unless ambiguous"). Opening a PR from current main would both textually conflict with #641 and produce self-contradictory guidance.Holding off until #641's fate is decided: if it merges, the right fix becomes rewording its new "required" sentence (stale-hint failure mode: the search is bounded to a window around
:start_line:, including the line-number-stripping fallback, so a shifted hint fails even when the SEARCH text exists verbatim elsewhere); if it stalls/closes, this issue's original 2-line plan applies cleanly.myk1yt commentedon Oct 30, 2026
Claiming — addressed in #2248 (stale :start_line: bounded-fail now retries the full file, gated on a unique fuzzy match above the configured threshold; ambiguous targets get a precise error instead of a guessed edit).