[BUG] Claude Code CLI hangs indefinitely after sending result event in stream-json mode
Bug Description
Claude Code CLI hangs indefinitely after successfully completing a task and sending the final {"type":"result","subtype":"success"} event. The process remains running with stdout open, never exiting cleanly, requiring manual SIGINT (CTRL+C) or SIGKILL to terminate.
Environment
- Platform: Linux (Ubuntu 22.04, kernel 6.8.0-100-generic)
- Claude CLI version: 2.1.38
- Node.js: v20.20.0
- Output Format:
--output-format stream-json - Flags:
--verbose --dangerously-skip-permissions - Runtime: ~18 minutes of active session
Steps to Reproduce
- Run Claude Code CLI in headless mode with stream-json output:
``bash``
claude --output-format stream-json --verbose --dangerously-skip-permissions --model claude-opus-4-5-20251101 -p "..." --append-system-prompt "..."
- Let Claude work on a task that involves multiple tool uses (in this case: 82 turns, ~18 minutes)
- Claude completes successfully:
- Outputs
{"type":"result","subtype":"success","duration_ms":1082218,...,"total_cost_usd":5.573962} - Task is functionally complete (PR marked ready, comments posted, etc.)
- Process hangs - stdout remains open, process doesn't exit
- Wait 5+ minutes - no activity, process still running
- Only CTRL+C (SIGINT) or SIGKILL terminates the process
Expected Behavior
After sending {"type":"result"} event, the CLI should:
- Close stdout stream
- Exit with code 0
Actual Behavior
{"type":"result","subtype":"success"}is sent- stdout remains open
- Process hangs indefinitely
- No further output
- Exit code upon SIGINT: 130 (128 + SIGINT)
Evidence from Logs
Timeline (from session 2ab1d239-9581-4d03-a895-af10c9fcb863):
| Timestamp | Event |
|-----------|-------|
| 21:10:17.168Z | Result event sent: {"type":"result","subtype":"success",...} |
| 21:10:17.169Z | Cost captured, result summary processed |
| 5 min 26 sec | NO ACTIVITY - PROCESS HUNG |
| 21:15:43.123Z | User interrupted with CTRL+C |
| 21:15:43.127Z | Exit code: 130 |
Result Event (last output before hang):
{
"type": "result",
"subtype": "success",
"is_error": false,
"duration_ms": 1082218,
"duration_api_ms": 940758,
"num_turns": 82,
"result": "I've completed the implementation...",
"session_id": "2ab1d239-9581-4d03-a895-af10c9fcb863",
"total_cost_usd": 5.573962
}
Related Issues
This appears to be the same or similar root cause as:
- #1920 - Missing Final Result Event in Streaming JSON Output (intermittent)
- #24478 - Claude Code CLI freezes and becomes unresponsive
- #24481 - CLI hangs indefinitely on simple queries
However, in this case:
- The result event IS sent (unlike #1920 where it's missing)
- The hang occurs AFTER the result event, not during execution
- The process appears to be in a state where it's waiting for something that never happens
Hypothesis
Based on code analysis, the issue appears to be that after sending the result event:
- Claude Code doesn't close its stdout stream
- The process remains in some waiting state
- No cleanup/exit routine is triggered
This causes any consumer using for await iteration or stream.on('end') to never receive the end signal.
Impact
- Automation: Completely breaks CI/CD pipelines using Claude Code CLI
- Resources: Stuck processes accumulate, consuming memory
- Reliability: Users must manually monitor and kill processes
Workaround
The consuming application can implement a timeout after receiving the result event:
if (data.type === 'result') {
// Process result...
setTimeout(() => {
process.kill(childPid, 'SIGKILL');
}, 30000);
}
Session Information
- Session ID:
2ab1d239-9581-4d03-a895-af10c9fcb863 - Full log file: Available at https://gist.githubusercontent.com/konard/309a5a535c0afc50e6a444f7f8b30d2a/raw/dc882237021646a4aa09320ecf26b8d03c434c65/2ab1d239-9581-4d03-a895-af10c9fcb863.log
- Reporting issue: https://github.com/link-assistant/hive-mind/issues/1280
Possible Fix Areas
- Ensure stdout is flushed and closed after writing result event
- Call
process.exit()explicitly after result event - Check for any pending timers/promises that prevent clean exit
- Investigate if MCP servers are keeping the process alive
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗