Agent SDK: query() stream hangs 15-30 min after last tool call before emitting ResultMessage
Resolved 💬 4 comments Opened May 14, 2026 by volley-ardy Closed Jun 20, 2026
Environment
claude-agent-sdk0.1.81- Bundled Claude Code CLI 2.1.139
- Python 3.12, Docker, Amazon Linux 2 (EC2 t3.large)
- Model: claude-opus-4-6
Problem
The query() async generator hangs for 15-30 minutes between the last ToolUseBlock message and the final ResultMessage. During this gap:
- No
AssistantMessage(TextBlock or ToolUseBlock) is yielded - No
ResultMessageis yielded - The CLI process is alive (0.9-1.2% CPU)
- Zero outbound TCP connections — the CLI is not making API calls
- stderr produces no output (even with
--verbose) - The
stderrcallback onClaudeAgentOptionsreceives nothing include_partial_messagesnot tested yet
The agent completes all tool calls in 30-90 seconds, then the stream goes silent for 15-30 minutes until our asyncio.timeout kills it.
Reproduction
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions(
system_prompt="...(~3K tokens)...",
model="claude-opus-4-6",
max_turns=25,
max_budget_usd=2.0,
permission_mode="bypassPermissions",
mcp_servers={
"snowflake": {"command": "mcpSnowflake", "env": {...}},
"dbt": {"command": "dbt-mcp", "env": {...}},
# + 3 more stdio MCP servers
},
allowed_tools=["mcp__snowflake__*", "mcp__dbt__*", ...],
cwd="/home/agent/workspace",
)
async for message in query(prompt="...", options=options):
# ToolUseBlock messages arrive normally for 30-90 seconds
# Then the generator blocks here for 15-30 minutes
# No messages yield until our timeout kills the process
pass
Timeline from logs (typical)
22:14:28 — query() started
22:14:43 — TOOL_CALL: ToolSearch (normal)
22:14:46 — TOOL_CALL: mcp__snowflake__readQuery (normal)
22:15:08 — TOOL_CALL: Bash (normal)
22:15:27 — TOOL_CALL: mcp__snowflake__readQuery (last tool call)
... 28 minutes of silence — zero messages yielded ...
22:43:xx — asyncio.timeout fires, process killed
What we checked
- No network activity during the gap —
/proc/PID/net/tcpshows zero outbound connections. The CLI is not calling the Anthropic API. - Process is alive —
docker topshows 0.9-1.2% CPU on theclaudeprocess throughout the gap. - TextBlock/ToolResultBlock never emitted — We log all block types in
AssistantMessage.content. OnlyToolUseBlockappears.TextBlockappears exactly once (at the start, before tool calls).ToolResultBlocknever appears. - stderr callback receives nothing —
ClaudeAgentOptions(stderr=callback)— callback never fires during the gap. - Not model-specific — Happens on both
claude-opus-4-6and during retries. - Thread context correlation — Seems more likely on follow-up questions where thread context (prior conversation) is prepended to the prompt. Simple first-message queries complete in 1-2 minutes.
- Setting
max_budget_usd=2.0on a DIFFERENT query made it complete in 90 seconds — suggesting the budget cap may prevent whatever internal loop causes the hang.
Impact
Every complex query that involves tool calls (which is all of them) has a ~50% chance of hanging for 30 minutes and timing out. Simple metric lookups work fine. This makes the agent unusable for the investigation-style queries it was built for.
Questions
- Is the bundled CLI doing internal compaction/context management between turns that could take 15-30 min?
- Does
include_partial_messages=Truesurface intermediate state during this gap? - Is there a known issue with the CLI hanging after stdio MCP tool execution?
- Could having 5+ MCP servers (all stdio) cause the CLI to stall on inter-process communication?
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗