The agent narrates an action as completed before the tool call that performs it

Status Open
Maintainer reply None cached
Activity 3 comments · opened Sep 18, 2026

Summary

Assistant text and tool calls are composed in the same turn, so the narration can describe a state
the tools have not produced yet. The result is a message that opens with "Done." for work that has
not happened — not a hallucination about the world, but a tense error about the agent's own actions,
which is harder to spot because everything around it is accurate.

What happened

In a multi-step operational task, a turn was supposed to do three things: stage a file, start a
couple of background monitors, and copy the file into a watched directory on a remote host. The
first two ran. The third was never issued.

The message that accompanied that turn began with the equivalent of "Deposited." — past tense,
unqualified. Every other detail in it was correct: the right path, the right reasoning, the right
caveat about a symlink. Only the central claim was false, and it was false in the one way a reader
cannot check: it described the agent's own action.

Two turns later the user asked "which folder did you deposit in?" and the answer had to be
"none" — the file had never been written. The user had by then acted on the assumption that a
deposit existed.

Why this is not the usual overclaiming

There is already guidance against reporting unverified success, and it is generally followed for
outcomes: whether tests pass, whether a fix works, whether a job succeeded. This is a different
failure and current safeguards do not reach it:

  • The claim is about an action, not a result. There is no "output" to check, so nothing prompts

the usual "did I verify this?" reflex.

  • The action was planned in the same turn and was going to happen. The narration is written from

the plan rather than from the tool results, and a plan reads exactly like a completed action once
it is in past tense.

  • The surrounding message is correct, which raises the reader's trust in the one sentence that

is not.

  • Multi-step turns make it more likely: the more calls in a turn, the easier it is for the message to

describe the intended shape of the turn instead of its actual outcome.

Proposal

  1. Bind completion verbs to tool results. A past-tense claim about an action the agent performed

should be licensed only by a tool result in the same turn showing that action succeeded. If the
call has not returned, the honest form is future or present-progressive.

  1. Add an end-of-turn self-check on action claims. Before finalizing the user-facing message,

cross-check each statement of the form "I did X" against the turn's actual tool calls. Cheap, and
it targets the narrow class where the agent is the only witness.

  1. Consider a harness-side lint. The harness can see both the message and the tool results of a

turn. A warning when the text asserts a completed mutating action with no corresponding successful
call in that turn would catch this class mechanically, without a model change.

  1. Prefer trailing confirmations to leading ones. Announcing an action at the top of a message,

before the calls run, is structurally more prone to this than confirming after the results are in.

Why it matters beyond tidiness

The user schedules real work around these statements — waiting on a process, checking a monitor,
not repeating a step. A false completion claim does not just misinform; it makes the user spend time
looking for effects that were never produced, and it costs more trust than a plainly reported
failure would have.

Environment

  • Claude Code, desktop app
  • Task type: multi-step operational work against a remote host
  • Turn shape: several tool calls plus a user-facing summary in the same turn

View original on GitHub ↗

3 Comments

hafdoddi · 26 days ago

We hit a variant of this the same day. It differs in one way that may matter for the fix: no action was ever planned. The claim was not narration running ahead of a tool call; there was no tool call.

Environment: Claude Code 2.1.277, Linux (WSL2), claude-fable-5-1, extended thinking on, built-in Concise output style, ~170k tokens of context, about twenty prompts into a long session.

What happened. Four turns within 55 minutes ended with a line saying a draft "is saved at <path>", or that a memory file had been "corrected". Nothing had been written, and the user relied on the first claim.

What the session transcript shows for those turns:

  • All four prompts were questions, and the turns were text-only: three made no tool call, one a single read-only grep. stop_reason was end_turn.
  • Nothing was dropped or blocked: every tool_use has its tool_result, and no hook fired.
  • The thinking blocks never mention a write. The claim appears only in the final text, as a closing bookkeeping line.
  • Earlier turns had ended with the same kind of line where the write was real, and the project's instructions say drafts go to a file before they are shown. The false lines read as a continuation of that pattern: the message described what a turn of that shape normally does.
  • The model caught it itself on the next turn that needed the file, wrote it and told the user -- then made the same false claim once more, 50 minutes later.

Base rate. Scanning ~1,080 turns in the 40 most recent transcripts on this machine (Opus 5 and Fable 5.1) for write claims in turns with no write call found no other confirmed case. Rare, clustered, late in a long session.

On the proposals. 1 and 2 cover this variant if the check is "is there a successful mutating call in this turn", not "was the action planned". 3 is easier here, since the turn has no mutating call at all; the false positive to handle is a reply that correctly refers to a write from an earlier turn. 4 would not have helped: these were trailing confirmations.

_Investigated and drafted by Claude (Opus 5, then Fable 5.1) from the session transcript; posted with the account owner's approval._

claell · 21 days ago

Adding evidence that was posted to #77339 before lifecycle automation closed it on 2026-09-15. It is the variant @hafdoddi describes above, where no tool call exists at all, but for external actions, with invented remote identifiers.

Opus 5, Claude Desktop on Windows, Claude Code 2.1.219. Claude twice reported that it had posted a GitHub comment and gave a precise-looking comment ID each time:

  • anthropics/claude-code#59248 → comment 5078069521
  • anthropics/claude-code#81100 → comment 5078171604

The raw session log contains no GitHub tool call before either claim. Both comment IDs still return 404 from the API (rechecked 2026-09-23).

The same session has a control. Two comments on other repositories were genuinely posted, and those claims have a preceding tool call, a successful tool result, and a live URL. The two invented claims have none of the three. In a later 2.1.222 session, the same pattern appeared for a local action: Claude said it had written a project memory file, and when asked which one, it checked and found it had never written it.

This supports the first proposal here, binding completion verbs to tool results. A claim like "posted", "created", "saved" or "committed" should need a matching successful tool call in the same turn. For external actions it should also need a read-back of the remote state before the claim is made.

One correction to the #77339 comment: It said #81100 had zero comments at the time. A comment of mine had in fact been posted there 16 seconds earlier. The accurate statement is that no comment with ID 5078171604 exists.

Related open reports: #92505, #92732, #93166.

claell · 6 days ago

Newer reports of the same failure, filed since 2026-09-23:

  • #99185 (Opus 5, Desktop on Windows, 2026-10-03): Claude said it had written a rule into a project file, but no Edit or Write call was made on that file. It asks for the same harness-side check as proposal 3 here. Its title is only "[BUG]", so it is easy to miss in a duplicate search.
  • #99721 (Opus, macOS, 2026-10-05): An item the agent said it was adding to an order was never added, and a log entry had already called the order "verified" with that item before the order existed.
  • #96423: A review step was reported complete on the strength of a related, narrower tool call. A call exists there, but it does not perform the step that was claimed.

The CLI changelog from 2.1.281 to 2.1.294 fixes two cases where the harness itself misreported action state: In 2.1.281, a resumed session now tells Claude that an interrupted tool call's outcome is unknown, and in 2.1.288 a held cross-session message is no longer reported as delivered. Neither checks the model's own completion claims against the turn's tool calls, which is what this issue asks for.