[Bug] Async hooks receive empty stdin on macOS (0 bytes) — works on Linux

Resolved 💬 3 comments Opened Mar 24, 2026 by wiktordepina Closed Mar 28, 2026

Preflight Checklist

  • [x] I have searched existing issues and this has not 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?

Async hooks ("async": true) receive zero bytes on stdin on macOS. The same hook configuration receives full JSON input on Linux. Synchronous hooks work correctly on both platforms.

This affects all async hook types (tested with SessionEnd and PreCompact). The hook process's stdin is completely empty — not truncated, not missing a newline, but 0 bytes.

What Should Happen?

Async hooks should receive the same JSON input on stdin as synchronous hooks, regardless of platform. Per the hooks reference docs, all hook types receive JSON with session_id, transcript_path, cwd, etc.

Steps to Reproduce

  1. Add this to ~/.claude/settings.json:
{
  "hooks": {
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'echo \"STDIN_LEN=$(cat | wc -c)\" >> /tmp/hook-stdin-test.log'",
            "timeout": 5,
            "async": true
          }
        ]
      }
    ]
  }
}
  1. Start and exit a Claude Code session
  2. Check /tmp/hook-stdin-test.log

macOS result: STDIN_LEN=0

Linux result: STDIN_LEN=290 (full JSON with session_id, transcript_path, etc.)

  1. Remove "async": true — macOS now also receives full JSON.

Error Messages/Logs

No error from Claude Code itself. The hook process simply receives empty stdin, causing downstream JSON parsing to fail:

Expecting value: line 1 column 1 (char 0)

Environment

  • Claude Code version: 2.1.81
  • macOS: Darwin arm64 (Apple Silicon), also tested via claude --print
  • Linux: confirmed working with identical config on same Claude Code version (2.1.81)
  • Shell: zsh (macOS), bash (Linux)

Related Issues

  • #30509 — reported as "missing trailing newline" on async hooks (macOS), but likely the same root cause. The reporter's bash read test may have masked the fact that stdin is entirely empty, since read returns exit 1 for both "no newline" and "no data".

Claude Model

Opus (but model is irrelevant — this is a hook execution issue)

Is this a regression?

I don't know — async hooks have always been empty on macOS in my testing. Works on Linux.

Platform

Anthropic API (via AWS Bedrock)

Operating System

macOS (Darwin 25.3.0, arm64)

Terminal/Shell

zsh

View original on GitHub ↗

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