[BUG] Model re-reads an unchanged file in a loop, ignoring repeated "Wasted call — file unchanged" rejections (bare rejection gives a context-corrupted model nothing to recover from)
Preflight
- This is a single bug report.
- Found by post-hoc audit of the session transcript JSONL.
What's Wrong?
The model reads a file, receives the content, then on a later turn requests the same file
again with no intervening change. The harness returns Wasted call — file unchanged since The model does not adapt — it
your last Read. Refer to that earlier tool_result instead.
re-issues the same read, gets the same rejection, and repeats. This is not a one-off: it
appeared independently in a subagent (during planning) and in the main session (during
implementation) in the same session.
Two distinct problems:
- Model: repeated identical rejections do not change behavior; there is no loop-escape
heuristic ("I already have this; stop asking").
- Harness: the
Wasted callrejection returns no content and no actionable
alternative, so a model that has lost track of context has nothing to recover from — it
can only re-ask.
Environment
- Claude Code 2.1.156 (desktop)
- Model: claude-opus-4-8
Evidence
- Main session:
Readof two files succeeds, then both are re-read on subsequent turns;
three consecutive Wasted call rejections; the loop continues until the session stalls with
no output. (In this instance the loop was triggered/worsened by a server-side fault that
returned duplicate message.ids, breaking the model's view of what it had already read —
filed separately — but the loop behavior is general.)
- Plan subagent: ~7
Wasted callevents on several files during planning; the agent only
progressed by falling back to cat.
The recurrence across two independent contexts in one session indicates a systemic handling
gap, not random drift.
Expected vs Actual
- Expected: a redundant read is satisfied from cache (or rejected once, after which the
model proceeds); it never becomes an unbounded loop.
- Actual: re-reads loop on repeated bare rejections until the session stalls.
Asks
- Give the model a loop-escape: after one
Wasted callfor a given file, do not re-issue the
identical read.
- Reconsider the rejection payload — return the cached content (or a usable reference) rather
than a bare "refer to the earlier result," which a context-corrupted model cannot act on.
- As a backstop, cap repeated identical failing tool calls at the harness level (companion
report, filed separately).
Related issues reviewed — why this is distinct
- #53578 (closed,
stale) — "Agent loops on Read tool when saving memory — re-reads same
file repeatedly." Nearest behavioral match, but different trigger (intent-drift while
saving memory, not corrupted responses), and it does not name the no-content-rejection half.
Closed as stale, not fixed — this report should reopen/extend it.
- #63935 (closed) — "Regression in 2.1.158: spirals into redundant/invented tool calls
during file reads." Same surface, but pinned to a 2.1.158 regression (2.1.157 clean); this
occurred on 2.1.156, so the behavior predates that regression.
- #55042 (open), #60722 (closed) — share only the harness half (rejection returns no
content) but are triggered by rewind/revert state desync, not voluntary re-reads.
- #60684 (open) — the inverse (stale cache when a file is edited externally).
Unique here: a voluntary re-read of a genuinely-unchanged file + the model ignoring repeated
identical rejections + the bare no-content rejection + reproduced in both a subagent and the
main session in one session.
4 Comments
Related reports from the same session audit:
message.ids, breaking the model's view of what it had already read. The re-read behavior is general, but #64880 is the proximate cause here.Periodic verification — June 2026
Checked against Claude Code v2.1.185 (latest release as of 2026-06-21).
Reproduction test: ℹ️ Not testable this run — the unchanged-file re-read loop depends on a context-corrupted model state that isn't reproducible on demand.
Release notes through v2.1.185: no mention of improved rejection feedback for repeated unchanged-file reads. (v2.1.185 fixed empty thinking-only turns by re-prompting once, but that is a different code path.)
This comment is posted automatically to prevent stale-bot closure (threshold: 28 days inactive). Reporter (@blwfish) will close upon confirming resolved.
Periodic verification — August 2026
Checked against Claude Code v2.1.220 (latest release as of 2026-08-01).
Reproduction test: ℹ️ Not testable this run — the loop requires a context-corrupted model state that cannot be induced on demand.
Release notes through v2.1.220: no mention of a fix. The underlying request stands regardless of the loop's frequency — a bare "Wasted call — file unchanged" rejection gives a confused model no recovery affordance, and that string is unchanged.
Note: this issue was auto-labeled
staleon 2026-07-19 with no maintainer response at any point.This comment is posted automatically every ~10-20 days to prevent stale-bot closure. Reporter (@blwfish) will close upon confirming resolved.
Periodic verification — August 2026
Checked against Claude Code v2.1.238 (latest release as of 2026-08-21).
Reproduction test: ℹ️ Not testable passively — reproducing this requires the "Wasted call — file unchanged" rejection path to fire during a live session; it cannot be provoked from transcript data after the fact.
Release notes through v2.1.238: no mention of a fix. The closest entries touch adjacent surfaces only (v2.1.234 fixed session-scoped permission denies being dropped for background subagent prompts) and do not address a bare rejection giving the model nothing to recover from.
This comment is posted automatically every ~20 days to prevent stale-bot closure (threshold: 28 days). Reporter (@blwfish) will close upon confirming resolved.