Missing Final Result Event in Streaming JSON Output with sdk
Bug Description
Summary
Claude Code CLI fails to send the required final {"type":"result",...} event in streaming JSON mode after successful tool execution, causing the process to hang indefinitely despite completing the conversation functionally.
Environment
- Claude Code Version: v1.0.18
-
Output Format:
--output-format stream-json - Usage: Via Go SDK wrapper (https://github.com/humanlayer/humanlayer/tree/main/claudecode-go) which follows the official SDK specification
Reproduction
This bug is intermittent - same query patterns sometimes work, sometimes hang:
Working execution (session dae3c2a4-1abf-4e77-99c2-1e3de1a8ac4a):
- Same multi-line TUI analysis query
- Proper completion with final result event
Hanging execution (session e025afdd-d550-4718-acd5-21f01edbb244):
- Identical query pattern and tool execution
- Missing final result event, process hangs
Evidence of Claude Code Bug
1. SDK Specification Violation
Per official SDK docs:
"Each conversation begins with an initial
initsystem message, followed by a list of user and assistant messages, followed by a finalresultsystem message with stats."
2. Event Sequence Comparison
✅ Working Session Event Sequence:
{"type":"system","subtype":"init","session_id":"...","tools":[...]}
{"type":"assistant","message":{"content":[{"type":"text","text":"..."}]}}
{"type":"assistant","message":{"content":[{"type":"tool_use","id":"...","name":"TodoWrite",...}]}}
{"type":"user","message":{"content":[{"type":"tool_result","tool_use_id":"...","content":"..."}]}}
{"type":"result","subtype":"success","session_id":"...","cost_usd":2.90831585,"num_turns":62,...}
❌ Hanging Session Event Sequence:
{"type":"system","subtype":"init","session_id":"...","tools":[...]}
{"type":"assistant","message":{"content":[{"type":"text","text":"..."}]}}
{"type":"assistant","message":{"content":[{"type":"tool_use","id":"...","name":"TodoWrite",...}]}}
{"type":"user","message":{"content":[{"type":"tool_result","tool_use_id":"...","content":"..."}]}}
// <-- MISSING: No {"type":"result",...} event, process hangs here
3. Go SDK Implementation Verification
Our Go wrapper correctly implements the SDK specification:
// Wait for BOTH process termination AND stdout parsing completion
go func() {
session.SetError(cmd.Wait()) // Wait for process exit
<-parseDone // Wait for stdout EOF + parsing complete
close(session.done) // Only then signal completion
}()
The SDK properly waits for Claude Code to:
- Send the final
resultevent - Close stdout
- Exit the process
Since Claude Code never sends step 1, steps 2-3 never happen.
4. Process State Evidence
# Process still running 30+ minutes after functional completion
$ ps aux | grep 89349
allison 89349 node .../claude --print "..." --output-format stream-json
Impact
- SDK integration sessions hang indefinitely
- Process accumulation over time
- Daemon sessions show as "running" when functionally complete (daemon layer: https://github.com/humanlayer/humanlayer/tree/main/hld)
- Prevents reliable automation with Claude Code
Workaround Attempted
Adding timeouts to detect hung processes, but this is clearly a Claude Code CLI issue that should be fixed upstream.
Additional Context
- Bug appears to be related to tool execution completion handling in streaming mode
- Both successful and hanging sessions involve the same
TodoWritetool - Functional completion occurs (response provided, tool executed successfully)
- Only the final signaling is broken
Session IDs for Investigation
-
Working:
dae3c2a4-1abf-4e77-99c2-1e3de1a8ac4a(bug report filed from the session by doing--resumeinteractively after the sdk run completed) / Claude session70c4f4f8-5aff-401e-8e0a-782f8613ae8d -
Hanging:
e025afdd-d550-4718-acd5-21f01edbb244(session not available to resume, showing claude code also doesn't believe it's finsihed) / Claude sessionc31fdd13-0cd4-4eb3-8349-f7ef23a55135
Raw event data available upon request for debugging.
Repository Context
This bug was discovered while developing a Claude Code integration for the HumanLayer project (https://github.com/humanlayer/humanlayer), which includes:
- claudecode-go: Go SDK wrapper for Claude Code CLI
- hld: Daemon layer that manages Claude Code sessions and stores conversation events
Environment Info
- Platform: macos
- Terminal: ghostty
- Version: 1.0.18
- Feedback ID: 0ed3e58e-bf98-46af-b0eb-9ff633e66a3f
Errors
[]