[BUG] Hook callback errors (Stream closed) on every tool call when using Agent SDK with bypassPermissions
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When using the Claude Agent SDK (Python) with permission_mode="bypassPermissions", every single tool call produces a noisy Error in hook callback hook_0: Stream closed error. The error dumps ~50 lines of minified Bun CLI source code to stderr on each tool call, making logs unreadable.
The errors are non-fatal — all tools complete successfully — but a typical agent session with 20-30 tool calls generates thousands of lines of error noise.
This started with claude-agent-sdk>=0.1.29 which introduced new hook events (SubagentStop, Notification, PermissionRequest). The bundled Claude CLI (v2.1.31+) appears to fire these hook callbacks even in bypassPermissions mode, and the sendRequest call fails because the stream context is wrong.
Also filed on the Python SDK: https://github.com/anthropics/claude-agent-sdk-python/issues/554
Error Messages/Logs
Every tool call produces this (two consecutive calls shown):
[claude 10:58:16] Using tool: Read → CLAUDE.md
Error in hook callback hook_0: 6339 | Claude Code has been suspended. Run `fg` to bring Claude Code back.
6340 | Note: ctrl + z now suspends Claude Code, ctrl + _ undoes input.
6341 | `)},FL=()=>{l1((SL)=>SL+1)};return uI?.on("suspend",J$),uI?.on("resume",FL),()=>{
uI?.off("suspend",J$),uI?.off("resume",FL)}},[uI]);let Cf=lA.useMemo(()=>b5(eA).filter(at),
[eA]),kf=lA.useMemo(()=>{if(!ZA)return null;let J$=aL.filter((G9)=>G9.type==="progress"&&
G9.data.type==="hook_progress"&&(G9.data.hookEvent==="Stop"||G9.data.hookEvent==="SubagentStop"));
...truncated ~50 lines of minified source...
6344 | `)}async sendRequest(H,$,A){let L=HEB.randomUUID(),I={type:"control_request",request_id:L,
request:H};if(this.inputClosed)throw Error("Stream closed");
error: Stream closed
at sendRequest (/$bunfs/root/claude:6344:133)
at sendRequest (/$bunfs/root/claude:6344:627)
at <anonymous> (/$bunfs/root/claude:6344:1305)
at callback (/$bunfs/root/claude:6344:1451)
at _U1 (/$bunfs/root/claude:3151:1288)
at _U1 (/$bunfs/root/claude:3151:1525)
at <anonymous> (/$bunfs/root/claude:3144:1239)
at A (/$bunfs/root/claude:1240:1491)
at MK$ (/$bunfs/root/claude:1240:1641)
at iS (/$bunfs/root/claude:3144:5408)
[claude 10:58:16] Tool completed ← tool still succeeds
[claude 10:58:16] Using tool: Glob → *.{eslintrc,prettierrc,editorconfig} in .
Error in hook callback hook_0: 6339 | Claude Code has been suspended...
<exact same error block repeats>
[claude 10:58:16] Tool completed ← tool still succeeds
Steps to Reproduce
- Install
claude-agent-sdk>=0.1.29(Python) - Use
query()withClaudeAgentOptions(permission_mode="bypassPermissions") - Run any agent session that uses tools (Read, Glob, Grep, Bash, etc.)
- Every tool call produces the
Error in hook callback hook_0: Stream closederror
What Should Happen?
In bypassPermissions mode, hook callbacks that attempt stream-based permission requests should either:
- Not fire at all (permissions are bypassed, no need to request)
- Be silently caught instead of dumping minified source code + stack traces to stderr
Root Cause
The minified source in the error shows the SubagentStop/Stop hook event handling code (introduced in SDK v0.1.29). The sendRequest function checks this.inputClosed and throws "Stream closed" — the parent process hook tries to communicate over a stream that doesn't exist or is already closed when running in bypass mode.
Workaround
Pin claude-agent-sdk<0.1.29 (v0.1.28 with bundled CLI v2.1.30). This eliminates the errors completely — the new hook events didn't exist yet.
Environment Info
- Platform: Linux (Ubuntu 24.04 / Zorin OS 18, kernel 6.14.0-37-generic x86_64)
- Claude Code CLI: 2.1.34
- claude-agent-sdk (Python): 0.1.29, 0.1.30, 0.1.31 all reproduce
- Python: 3.12.3
- Node.js: v24.13.0
Claude Model
Opus (claude-opus-4-6), also reproduces with claude-opus-4-5-20251101
Is this a regression?
Yes, this worked in a previous version
Last Working Version
claude-agent-sdk==0.1.28 (bundled CLI v2.1.30)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗