Skip to content

PromptResponse and final usage_update both withheld on a normal finished turn, flushed only by session/cancel (0.59.0, sdk 0.3.207) #896

Description

@Seluj78

Summary

Same defect family as #825 and #688: the adapter finishes an agent turn but never returns the JSON-RPC result (PromptResponse) for the in-flight session/prompt. The session sits "running" from the client's perspective until the client gives up and sends session/cancel.

This report adds a clean, minimal reproduction that pins down one detail the earlier threads left fuzzy: the adapter also withholds the end-of-turn usage_update (the cost-populated accounting frame), and only emits it when poked by session/cancel. In other words, at cancel time the adapter clearly still holds a fully-finished turn (it can produce the final cumulative usage with cost the instant it is asked to cancel), it just never surfaced the turn end on its own.

Still reproduces on @agentclientprotocol/claude-agent-acp@0.59.0 (packaging @anthropic-ai/claude-agent-sdk@0.3.207), with CLAUDE_ENABLE_STREAM_WATCHDOG default-on. Follows up on the closed #825 (maintainer asked to be pinged on recurrence) and #688.

Reproduction

Normal agent turn, no slash command, no async sub-agent. The model ran a couple of read-only Bash/Terminal tool calls, then ended its turn. The client (agent-of-empires) records every session/update and synthesizes a Stopped event once the awaited session/prompt future resolves. Client-side event log plus the client's own tracing for one session:

11:22:06.9   seq 8364  tool_call_completed        (last tool: read files, success)
11:22:09.7   seq 8365  usage_update  cost:null    (mid-turn accounting frame)
             --- 120 s of total silence: no session/update of any kind ---
11:24:09.261 client silent-turn watchdog fires -> sends session/cancel
11:24:09.273 seq 8366  usage_update  cost:$13.70  (final cumulative usage, arrives only now)
11:24:09.273 seq 8367  turn resolves              (PromptResponse finally delivered as cancelled)

The two things worth noting:

  1. Between 11:22:09 and 11:24:09 the adapter emitted nothing: no agent_message_chunk, no tool_call, no usage_update, and crucially no PromptResponse. The turn was over (the model chose to end after the tool reads) but the adapter never signaled it.
  2. The cost-populated usage_update (8366) and the PromptResponse (8367) both landed in the same ~12 ms window, immediately after session/cancel. The cancel did not interrupt in-flight work; there was no in-flight work. It flushed a turn that had already completed.

Because the client only cancelled after a 120 s grace, the session showed "running" for two minutes after the agent had actually finished, then flipped to done. This is the user-visible symptom that led here.

Why this points at the adapter, not the model

The final cumulative usage frame carrying a non-null cost is the adapter's own end-of-turn accounting marker. That it can be produced the instant a cancel arrives means the turn's model work had genuinely finished; the adapter was holding a completed turn without surfacing it. So this is not a dropped/abnormal model stream (the #825 primary trigger) but a plain normal-turn end that the adapter failed to finalize, matching #688's "normal agent turns" shape.

Impact

Every occurrence wedges the session for the full client grace window (120 s here) and then can only be resolved by the client force-cancelling, which is indistinguishable at the protocol level from a real cancellation. A client that trusts the protocol would hang indefinitely; clients that add a watchdog pay the grace latency on every occurrence and lose the ability to tell a clean completion from a forced one. Observed frequency on our side: several times per day across sessions.

Environment

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions