PreToolUse/PostToolUse hook events not emitted in stream-json output

Resolved 💬 2 comments Opened Feb 20, 2026 by johannesCmayer Closed Feb 20, 2026

Description

When using --output-format stream-json (including via --permission-prompt-tool stdio / the Python SDK), SessionStart and Stop hooks emit hook_started and hook_response system messages in the stream. However, PreToolUse and PostToolUse hooks do not emit these messages, even though the hooks execute successfully (their side effects are observable).

Steps to Reproduce

  1. Configure a PreToolUse hook in ~/.claude/settings.json:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "command",
            "command": "date '+Hook fired: %Y-%m-%d %H:%M:%S'"
          }
        ]
      }
    ]
  }
}
  1. Start Claude Code with stream-json output:
claude --output-format stream-json --permission-prompt-tool stdio
  1. Ask Claude to use the Read tool.
  1. Observe the stream-json messages — no hook_started or hook_response system messages appear for the PreToolUse:Read hook.
  1. For comparison, SessionStart hooks do produce these messages:
{"type": "system", "subtype": "hook_started", "hook_id": "...", "hook_name": "SessionStart:startup", "hook_event": "SessionStart"}
{"type": "system", "subtype": "hook_response", "hook_id": "...", "hook_name": "SessionStart:startup", "outcome": "success", "output": "...", "exit_code": 0}

Expected Behavior

All hook lifecycle events (SessionStart, Stop, PreToolUse, PostToolUse, etc.) should emit hook_started/hook_response system messages in the stream-json output, so SDK consumers can observe hook execution.

Actual Behavior

Only SessionStart and Stop hooks emit these messages. PreToolUse and PostToolUse hooks execute silently — their side effects work, but no messages appear in the stream.

Environment

  • Claude Code version: 2.1.44
  • Platform: Linux (NixOS)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗