Sidechain messages occasionally not yielded through receive_response() despite being saved to <Session>.jsonl
Summary
Subagent (Task tool) messages are saved to history.jsonl with isSidechain: true but occasionally are not yielded through the receive_response() async generator. This causes assistant responses from subagents to be lost during streaming, even though
they're preserved in the session history file.
Expected Behavior
When a Task tool invokes a subagent that produces output:
- The subagent's output should be aggregated into the parent Task tool's
tool_result - OR the sidechain messages should be yielded through
receive_response() - All assistant responses should be available via the async generator
Actual Behavior
Occasionally, sidechain messages with large text content are:
- Saved to
history.jsonlwith"isSidechain": true - NOT yielded through
receive_response() - Result in empty parent Task tool results (
content: []) - Effectively lost during the streaming process
Steps to Reproduce
- Configure ClaudeSDKClient with a subagent
- Invoke the Task tool to trigger the subagent (may need multiple attempts)
- Iterate through
client.receive_response()to collect all messages - Compare received messages with entries in
<claude_config_dir>/history.jsonl
Observation:
-
history.jsonloccasionally contains assistant messages with"isSidechain": trueand large text content - These messages are not yielded through the async generator
- Tool result for the parent Task tool has empty content:
ToolResultBlock(tool_use_id='toolu_xxx', content=[])
Evidence
Message in history.jsonl:
{
"parentUuid": "ab3780f8-6529-4ae3-88ff-c003d2f7d722",
"isSidechain": true,
"timestamp": "2025-10-28T01:10:02.997Z",
"message": {
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "...13,022 characters of subagent output..."
}
],
"parent_tool_use_id": null
}
}
Expected sequence from receive_response(): 01:08:48 - AssistantMessage (Tool Use) 01:10:02 - AssistantMessage (Text - 13KB) ← MISSING 01:10:06 - AssistantMessage (Tool Use)
Actual sequence from receive_response(): 01:08:48 - AssistantMessage (Tool Use) 01:10:06 - AssistantMessage (Tool Use) ← Skipped directly here
Impact
- Data Loss: Subagent responses are occasionally not accessible via the async generator
- Inconsistency: history.jsonl contains messages that were never yielded
- Debugging Difficulty: Intermittent nature makes it hard to track when output is lost
Environment
- Claude Agent SDK Version: 2.0.26
- Python Version: 3.11
- Model: claude-sonnet-4-5-20250929
- Configuration: Using persistent session with continue_conversation=True
Code which I used
async with ClaudeSDKClient(options=self.options) as client:
await client.query(prompt=prompt)
async for message in client.receive_response():
message_count += 1
message_type = type(message).__name__
logger.info(
f"Claude Agent SDK stream query - Message: {message_type}"
)
logger.debug(f"Claude Agent SDK stream query - Message: {message}")
Compared the logs against the session.jsonl