claude-code - 💡(How to fix) Fix [BUG] UserPromptSubmit hooks hang indefinitely on Windows (stdin pipe not closed) [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#53177Fetched 2026-04-26 05:22:24
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×3commented ×2closed ×1

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.

Root Cause

Root Cause Hypothesis

Code Example

#!/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()

---

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 \".claude/hooks/my-hook.py\""
          }
        ]
      }
    ]
  }
}
RAW_BUFFERClick to expand / collapse

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

ConfigurationWindows ResultmacOS Result
{} (no hooks)~8s ✅Normal ✅
SessionStart hooks only (3 hooks, all read stdin)7s ✅Normal ✅
SessionStart + UserPromptSubmitHangs 5-11 minNormal ✅
Manual: echo '{}' | python3 hook.pyInstant ✅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.

extent analysis

TL;DR

The issue can be resolved by ensuring that the stdin pipe is properly closed for UserPromptSubmit hooks on Windows.

Guidance

  • Verify that the issue is indeed caused by the stdin pipe not being closed by checking the Claude Code source code for differences in how SessionStart and UserPromptSubmit hooks are handled.
  • Consider using a workaround such as adding a timeout to the json.load(sys.stdin) call to prevent it from hanging indefinitely.
  • Investigate the possibility of using a different method to read from stdin that does not rely on json.load(), such as using the sys.stdin.read() method with a specified buffer size.
  • Check the related issues (#46601 and #14219) to see if they provide any additional insight or potential solutions.

Example

import sys
import json

def main():
    try:
        # Add a timeout to prevent hanging
        import select
        if select.select([sys.stdin], [], [], 1)[0]:
            hook_input = json.load(sys.stdin)
        else:
            # Handle timeout
            print("Timeout occurred")
    except (json.JSONDecodeError, EOFError):
        return

if __name__ == "__main__":
    main()

Notes

The provided code snippet is a potential workaround, but it may not be the most elegant solution. A more permanent fix would likely involve modifying the Claude Code to properly close the stdin pipe for UserPromptSubmit hooks on Windows.

Recommendation

Apply workaround: Add a timeout to the json.load(sys.stdin) call to prevent it from hanging indefinitely, as shown in the example code snippet. This will allow the hook to continue executing even if the stdin pipe is not properly closed.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] UserPromptSubmit hooks hang indefinitely on Windows (stdin pipe not closed) [2 comments, 2 participants]