Remote-control session hangs forever mid-turn after connection drop (no stall detection on this path)
Environment
- Claude Code version: 2.1.220
- macOS (Darwin 25.5.0), Apple Silicon
- Session type:
claude remote-controldaemon → session started from the Claude mobile app (child processversions/2.1.220 --print --sdk-url https://api.anthropic.com/...)
What happened
Mid-turn, immediately after a Skill tool invocation (skill content attachment was the last event written to the transcript), the session stopped responding permanently. No assistant message, no tool call, no error — for 20+ minutes until I killed it manually.
Transcript tail (timestamps):
13:19:19.566assistant tool_use: Skill13:19:19.587tool_result: "Launching skill: ..."13:19:19.585attachment: skill content- (nothing after — file mtime frozen at 13:19:19)
Process state while hung
- Process alive, 0.0% CPU, main thread blocked in kevent (event loop idle, not spinning)
- MCP server children all healthy; no tool/Bash child processes running
lsof -i: multiple TCP connections to Anthropic endpoints held inCLOSEDstate by the process, oneESTABLISHED(presumably the SDK control websocket)- No new workspace/tool side effects — the turn never reached the model response
Analysis
The stream byte watchdog appears to be enabled by default (statsig tengu_stream_watchdog_default_on, idle timeout floor 300000ms per CLAUDE_STREAM_IDLE_TIMEOUT_MS handling), yet nothing recovered this turn even after 20+ minutes. So the hang seems to be on a path not covered by the stream watchdog — either the follow-up API request after the tool result never got retried once its socket died, or the --sdk-url control channel wait has no stall detection.
Recovery
SIGTERM was ignored; SIGKILL required. Transcript was intact and the session resumable via --resume.
Expected
Stall detection + retry on this path, or an error surfaced to the app UI, instead of an infinite silent hang (from the mobile app it just looks like an eternal spinner).
Not reliably reproducible — looks like a transient network drop mid-turn triggered it.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗