claude-code - 💡(How to fix) Fix [BUG] claude-agent-acp: streaming loop only exits on session_state_changed: idle, leaving Zed stop button stuck after every turn [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#57839Fetched 2026-05-11 03:24:02
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×2closed ×1commented ×1

The streaming loop in acp-agent.js exits the user-turn only on session_state_changed: { state: "idle" }. The result message — which is the actual semantic end of a Claude Code turn — falls through to a bare break; and the loop keeps waiting. When idle lags or never arrives, session.promptRunning stays true indefinitely.

Root Cause

In node_modules/@agentclientprotocol/claude-agent-acp/dist/acp-agent.js, case "result": ends with break; instead of returning. The only path that returns and closes the prompt is case "session_state_changed": when message.state === "idle". If idle never arrives, the loop hangs forever.

Code Example

if (!isTaskNotification) {
    return { stopReason, usage: sessionUsage(session) };
}
break;

---

return { stopReason, usage: sessionUsage(session) };
RAW_BUFFERClick to expand / collapse

Affected package: @agentclientprotocol/claude-agent-acp (verified on v0.31.4 and v0.33.1) Affected client: Zed (any recent version using the ACP integration)

Summary

The streaming loop in acp-agent.js exits the user-turn only on session_state_changed: { state: "idle" }. The result message — which is the actual semantic end of a Claude Code turn — falls through to a bare break; and the loop keeps waiting. When idle lags or never arrives, session.promptRunning stays true indefinitely.

Symptom (in Zed)

  • Stop button stays active after Claude finishes responding.
  • User has to click Stop manually before sending the next message (clicking Stop forces the stream closed, which finally lets the loop exit).
  • Sound alert (Zed's AcpThreadEvent::Stopped) is delayed by the same mechanism — it fires on stream close, not on result.

Repro

  1. Use Zed with the Claude Code ACP agent.
  2. Send any prompt — especially one that launches background tasks.
  3. After Claude's response finishes streaming, observe that the stop button stays active in the chat input.

Root cause

In node_modules/@agentclientprotocol/claude-agent-acp/dist/acp-agent.js, case "result": ends with break; instead of returning. The only path that returns and closes the prompt is case "session_state_changed": when message.state === "idle". If idle never arrives, the loop hangs forever.

Proposed fix

At the end of case "result": in acp-agent.js, replace the trailing break; with:

For v0.33+ (which has the isTaskNotification flag for autonomous task-notification followups):

if (!isTaskNotification) {
    return { stopReason, usage: sessionUsage(session) };
}
break;

The !isTaskNotification guard prevents an autonomous followup result from terminating the user-turn early.

For v0.31 and earlier (no isTaskNotification):

return { stopReason, usage: sessionUsage(session) };

result is the semantic end of the turn — the dependency on session_state_changed: idle is sloppy. Same return shape as the idle handler already uses.

Why this matters

Every Zed + Claude Code user hits this. It reads like a Zed bug to the user ("Zed's stop button is broken") but the fix lives in the Anthropic-published bridge.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] claude-agent-acp: streaming loop only exits on session_state_changed: idle, leaving Zed stop button stuck after every turn [1 comments, 2 participants]