Problem
When using the Claude Agent SDK (Python v0.2.87) with include_hook_events=True,
hook callbacks execute correctly but hook_started and hook_response system messages
are not emitted to the message stream, despite the --include-hook-events CLI flag
being passed to Claude Code.
Expected Behavior
According to the Agent SDK documentation,
when include_hook_events=True is set, the CLI should emit hook lifecycle events
(hook_started and hook_response messages with type: "system" and subtype in
["hook_started", "hook_response"]) into the message stream as HookEventMessage objects.
Actual Behavior
- Hook callbacks ARE returning correct
hookSpecificOutput format
--include-hook-events CLI flag IS being passed to Claude Code
- BUT
hook_started and hook_response system messages NEVER appear in the stream
- Only
init and status system messages appear
Steps to Reproduce
- Use Claude Agent SDK (Python) with
include_hook_events=True
- Register
PreToolUse and PostToolUse hooks
- Make a query that triggers tool use
- Listen to message stream with
client.receive_messages()
- Observe that
HookEventMessage objects never appear
Environment
- Claude Code CLI: 2.1.150
- Claude Agent SDK (Python): 0.2.87
- Output format: stream-json
- Mode: Streaming/bidirectional
Logs
Hook callbacks execute and print to console, confirming they're being called.
However, no hook_started or hook_response messages appear in the parsed message stream.
python api.py
INFO: Started server process [34419]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:51645 - "GET /chat HTTP/1.1" 200 OK
PreToolUse Event:
{'session_id': 'a561c82a-f6d7-4c89-b6f3-f839625b5dd1', 'transcript_path': '/Users/raman/.claude/projects/-Users-raman-Developer-claude-agent-sdk-backend/a561c82a-f6d7-4c89-b6f3-f839625b5dd1.jsonl', 'cwd': '/Users/raman/Developer/claude-agent-sdk/backend', 'permission_mode': 'default', 'hook_event_name': 'PreToolUse', 'tool_name': 'Bash', 'tool_input': {'command': 'find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l', 'description': 'Count files in current directory, excluding node_modules and venv'}, 'tool_use_id': 'toolu_019AASM8eM8emLZiY565mA7N'}
PostToolUse Event:
{'session_id': 'a561c82a-f6d7-4c89-b6f3-f839625b5dd1', 'transcript_path': '/Users/raman/.claude/projects/-Users-raman-Developer-claude-agent-sdk-backend/a561c82a-f6d7-4c89-b6f3-f839625b5dd1.jsonl', 'cwd': '/Users/raman/Developer/claude-agent-sdk/backend', 'permission_mode': 'default', 'hook_event_name': 'PostToolUse', 'tool_name': 'Bash', 'tool_input': {'command': 'find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l', 'description': 'Count files in current directory, excluding node_modules and venv'}, 'tool_response': {'stdout': ' 3', 'stderr': '', 'interrupted': False, 'isImage': False, 'noOutputExpected': False}, 'tool_use_id': 'toolu_019AASM8eM8emLZiY565mA7N', 'duration_ms': 59}
api.py
SSE UI STREAMS LOGS
data: {"type": "system", "subtype": "init"}
data: {"type": "system", "subtype": "status"}
data: {"type": "thinking", "thinking": "The user wants to find the number of files in the current working directory, ignoring node_modules and venv folders.\n\nI should use the Bash tool to run a command that counts files while excluding those directories. A good approach would be to use find command with appropriate exclusion patterns.\n\nLet me run a command to count the files."}
data: {"type": "tool_use", "tool": "Bash", "input": {"command": "find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l", "description": "Count files in current directory, excluding node_modules and venv"}}
data: {"type": "system", "subtype": "status"}
data: {"type": "thinking", "thinking": "The command found 3 files in the current working directory when excluding node_modules and venv directories."}
data: {"type": "text", "text": "There are 3 files in the current working directory (excluding node_modules and venv directories)."}
Problem
When using the Claude Agent SDK (Python v0.2.87) with
include_hook_events=True,hook callbacks execute correctly but
hook_startedandhook_responsesystem messagesare not emitted to the message stream, despite the
--include-hook-eventsCLI flagbeing passed to Claude Code.
Expected Behavior
According to the Agent SDK documentation,
when
include_hook_events=Trueis set, the CLI should emit hook lifecycle events(
hook_startedandhook_responsemessages withtype: "system"andsubtypein["hook_started", "hook_response"]) into the message stream asHookEventMessageobjects.Actual Behavior
hookSpecificOutputformat--include-hook-eventsCLI flag IS being passed to Claude Codehook_startedandhook_responsesystem messages NEVER appear in the streaminitandstatussystem messages appearSteps to Reproduce
include_hook_events=TruePreToolUseandPostToolUsehooksclient.receive_messages()HookEventMessageobjects never appearEnvironment
Logs
Hook callbacks execute and print to console, confirming they're being called.
However, no
hook_startedorhook_responsemessages appear in the parsed message stream.python api.py
INFO: Started server process [34419]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:51645 - "GET /chat HTTP/1.1" 200 OK
PreToolUse Event:
{'session_id': 'a561c82a-f6d7-4c89-b6f3-f839625b5dd1', 'transcript_path': '/Users/raman/.claude/projects/-Users-raman-Developer-claude-agent-sdk-backend/a561c82a-f6d7-4c89-b6f3-f839625b5dd1.jsonl', 'cwd': '/Users/raman/Developer/claude-agent-sdk/backend', 'permission_mode': 'default', 'hook_event_name': 'PreToolUse', 'tool_name': 'Bash', 'tool_input': {'command': 'find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l', 'description': 'Count files in current directory, excluding node_modules and venv'}, 'tool_use_id': 'toolu_019AASM8eM8emLZiY565mA7N'}
PostToolUse Event:
{'session_id': 'a561c82a-f6d7-4c89-b6f3-f839625b5dd1', 'transcript_path': '/Users/raman/.claude/projects/-Users-raman-Developer-claude-agent-sdk-backend/a561c82a-f6d7-4c89-b6f3-f839625b5dd1.jsonl', 'cwd': '/Users/raman/Developer/claude-agent-sdk/backend', 'permission_mode': 'default', 'hook_event_name': 'PostToolUse', 'tool_name': 'Bash', 'tool_input': {'command': 'find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l', 'description': 'Count files in current directory, excluding node_modules and venv'}, 'tool_response': {'stdout': ' 3', 'stderr': '', 'interrupted': False, 'isImage': False, 'noOutputExpected': False}, 'tool_use_id': 'toolu_019AASM8eM8emLZiY565mA7N', 'duration_ms': 59}
api.py
SSE UI STREAMS LOGS
data: {"type": "system", "subtype": "init"}
data: {"type": "system", "subtype": "status"}
data: {"type": "thinking", "thinking": "The user wants to find the number of files in the current working directory, ignoring node_modules and venv folders.\n\nI should use the Bash tool to run a command that counts files while excluding those directories. A good approach would be to use
findcommand with appropriate exclusion patterns.\n\nLet me run a command to count the files."}data: {"type": "tool_use", "tool": "Bash", "input": {"command": "find . -type f ! -path "/node_modules/" ! -path "/venv/" | wc -l", "description": "Count files in current directory, excluding node_modules and venv"}}
data: {"type": "system", "subtype": "status"}
data: {"type": "thinking", "thinking": "The command found 3 files in the current working directory when excluding node_modules and venv directories."}
data: {"type": "text", "text": "There are 3 files in the current working directory (excluding
node_modulesandvenvdirectories)."}