[BUG] UserPromptSubmit hooks hang indefinitely on Windows (stdin pipe not closed)

Status Fixed / completed
Maintainer reply None cached
Activity 3 comments · opened Apr 25, 2026 · closed Apr 25, 2026

Description

UserPromptSubmit hooks hang indefinitely on Windows when the hook script reads from stdin via json.load(sys.stdin). The same script works perfectly on macOS and also runs fine when tested manually on Windows with piped stdin (echo '{}' | python3 script.py).

SessionStart hooks using the exact same stdin-reading pattern (json.load(sys.stdin)) work correctly on Windows. Only UserPromptSubmit hooks exhibit this behavior.

Reproduction Steps

  1. Create a minimal UserPromptSubmit hook that reads stdin:
#!/usr/bin/env python
import json, sys

def main():
    try:
        hook_input = json.load(sys.stdin)
    except (json.JSONDecodeError, EOFError):
        return
    # immediately returns - no heavy processing

if __name__ == "__main__":
    main()
  1. Register it in .claude/settings.json:
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 \".claude/hooks/my-hook.py\""
          }
        ]
      }
    ]
  }
}
  1. Run on Windows: echo "hello" | claude --print
  2. Observe: hangs for several minutes before eventually responding (or never responds)

Expected Behavior

The hook should execute quickly (< 1 second) just as it does on macOS.

Actual Behavior

The hook hangs indefinitely. json.load(sys.stdin) appears to never receive EOF, causing it to wait for more data forever.

Debugging Evidence

| Configuration | Windows Result | macOS Result |
|---|---|---|
| {} (no hooks) | ~8s ✅ | Normal ✅ |
| SessionStart hooks only (3 hooks, all read stdin) | 7s ✅ | Normal ✅ |
| SessionStart + UserPromptSubmit | Hangs 5-11 min ❌ | Normal ✅ |
| Manual: echo '{}' \| python3 hook.py | Instant ✅ | Instant ✅ |

This confirms the issue is in how Claude Code pipes stdin to UserPromptSubmit hooks on Windows, not in the script itself.

Environment

  • OS: Windows 10 (Build 19045)
  • Python: 3.13.3
  • Claude Code: latest (auto-updated)
  • Shell: PowerShell 5.1
  • Drive: External SSD (USB), but also reproduced on internal paths

Related Issues

  • #46601 — Same stdin pipe issue but for Stop hooks on Windows (our case is UserPromptSubmit)
  • #14219 — Windows 11 hooks failing silently

Root Cause Hypothesis

Claude Code likely does not properly close/EOF the stdin pipe for UserPromptSubmit (and possibly Stop/PostToolUse) hook subprocesses on Windows. On macOS, POSIX pipe semantics handle this correctly. On Windows, the pipe handle may remain open, causing json.load(sys.stdin) or sys.stdin.read() to block waiting for more data that never arrives.

SessionStart hooks appear to use a different code path that correctly closes the pipe.

View original on GitHub ↗

3 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/46177
  2. https://github.com/anthropics/claude-code/issues/48009
  3. https://github.com/anthropics/claude-code/issues/36156

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

PLUTO-NIX · 5 months ago

Closing as duplicate. Same root cause as #46177, #48009, #36156 — Windows does not pipe stdin properly to hook subprocesses (TTY instead of pipe), causing hooks that read stdin to hang indefinitely.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.