Bug: Assistant continuation skipped after tool_result — turn ends silently
Summary
After tool execution completes and tool_result is returned to the CLI, the assistant turn sometimes ends silently — no API continuation call is made, no assistant response is generated. The user sees the tool finish but gets no output, requiring manual "resume" to proceed.
Environment
- Claude Code version: 2.1.69
- OS: macOS (Darwin 25.3.0, Apple Silicon)
- Model: claude-opus-4-6
Reproduction
This is not tied to a single tool. It occurs across multiple tool types:
| Tool(s) | Parallel? | Turn Duration | Sessions Affected |
|---------|-----------|---------------|-------------------|
| WebFetch x3 | Yes (3 parallel) | ~35s | 2 sessions |
| Agent (subagent) | Single | 4–10 min | 3 sessions |
| Bash / Grep | Single | 2–8 min | 2 sessions |
| Edit x4 + MCP Playwright | Mixed | 5 min | 1 session |
| MCP (Vercel, Playwright) | Mixed | 2–18 min | 2 sessions |
Total: 13 occurrences across 6 sessions.
Steps to reproduce (most reliable with WebFetch x3)
- Start a conversation that triggers 3 parallel
WebFetchcalls - All 3
tool_resultmessages are received successfully - Expected: Assistant generates a text response using the results
- Actual: Turn ends immediately. Stop hooks fire. No assistant message in the log.
Log Evidence
Session log analysis of the WebFetch case (02b95357):
L150: assistant stop=None tools=['WebFetch'] # 1st parallel call
L152: assistant stop=None tools=['WebFetch'] # 2nd parallel call
L154: assistant stop=tool_use tools=['WebFetch'] # 3rd parallel call (final)
L158: user tool_result (2,275 bytes) # Result 1
L161: user tool_result (3,643 bytes) # Result 2
L164: user tool_result (4,598 bytes) # Result 3
# ← NO assistant message here
L167: progress hook_progress Stop # Stop hooks begin
L168: system stop_hook_summary # preventedContinuation: false
L169: system turn_duration: 36,857ms # Turn ends
L171: user "resume" # User manually resumes
L173: assistant end_turn [generates response] # Works fine after resume
Key observations:
- No assistant message exists between L164 (last tool_result) and L168 (stop_hook_summary)
preventedContinuation: false— hooks did NOT block the turnstopReason: ""— empty, no explicit stop reason recorded- After user types "resume", the assistant generates the expected response normally with full context
Analysis
The CLI's turn state machine appears to incorrectly conclude the turn is finished after receiving all tool_result messages, without sending the continuation request to the API. This manifests in two patterns:
- Parallel tool calls (WebFetch x3, Edit x2+): Multiple
tool_resultmessages arriving asynchronously may cause a race condition in determining "all results received → send continuation" - Long-running tools (Agent 4-10min, MCP Playwright): Extended execution time may trigger a timeout or state transition that marks the turn as complete
Impact
- Users must manually type "resume" or similar to continue, often not knowing why the assistant stopped
- Actual user reactions from affected sessions: "계속 진행 뭔가 중단된 거 같아" (keep going, something seems interrupted), "다한거야? 왜 계속 중단해" (are you done? why do you keep stopping), "에러 때문에 멈춘거지?" (did you stop because of an error?)
- No error is surfaced — the turn simply ends silently
- 13 occurrences across 6 sessions over 4 days suggests this is a structural issue, not a rare edge case
Expected Behavior
After all tool_result messages are received for a stop_reason=tool_use assistant turn, the CLI should send a continuation API request so the assistant can generate its response.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗