[BUG] UserPromptSubmit hooks receive empty stdin on Windows — stdin piping broken
Preflight Checklist
- [x] I have searched existing issues and this hasn't 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?
UserPromptSubmit hooks receive empty stdin on Windows — stdin piping broken
Environment
- Claude Code version: 2.1.107
- OS: Windows 11 Enterprise (10.0.26100)
- Platform: Win32
- Node.js version: (used by hook system)
Summary
On Windows, UserPromptSubmit hook invocations receive empty stdin. This breaks any hook that depends on the hook input JSON passed via stdin by Claude Code.
Impact
Plugins and hooks that rely on stdin to receive session ID or other contextual data fail silently. Example:
- claude-mem plugin uses stdin to receive
session_idinUserPromptSubmithooks, which it needs to initialize sessions. With empty stdin, it falls back to{}and loses all session context, so no observations are ever recorded. - Any custom hook or plugin using stdin for
UserPromptSubmitwill fail the same way
Root cause hypothesis
One of:
- Claude Code on Windows doesn't pipe stdin to
UserPromptSubmithooks (regression or breaking change in hook contract) - The stdin relay through Node.js → cmd.exe → bun.cmd loses the piped data
- Windows-specific issue with how stdin is inherited by child processes in the hook system
Investigation notes
- Other hook types may work (SessionStart, PostToolUse, Stop, SessionEnd) — unclear if they have the same issue
- The
bun-runner.jsscript includes a workaround for Bun's EINVAL on pipes (#646), but it falls back to writing'{}'when no stdin is available, masking the original issue - macOS/Linux users likely don't experience this (Unix pipes are more reliable)
Additional context
This affects the claude-mem plugin (v12.1.0), which is completely non-functional on Windows due to this stdin issue. The plugin worker is healthy and MCP tools respond, but no observations are ever collected because session initialization fails.
Relevant stdin handling code:
bun-runner.jsline 158-188: buffers stdin from Node → Bun, falls back to'{}'- Affected hook:
UserPromptSubmithook invocation in Claude Code hook system
Workaround
Add the following to settings.json
"env": {
"CLAUDE_CODE_GIT_BASH_PATH": "C:\\Users\\YOURUSERNAME\\AppData\\Local\\Programs\\Git\\bin\\bash.exe"
}
Use "where bash" to locate your bash.exe
What Should Happen?
Expected behavior
UserPromptSubmit hooks should receive stdin containing JSON with at least:
session_idorid(session identifier)cwd(current working directory)prompt(user message text, if present)
As per the documented hook input contract for Claude Code.
Error Messages/Logs
Steps to Reproduce
Steps to reproduce
- Add a debug hook to
~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "tee C:/temp/debug_hook_stdin.json",
"timeout": 5
}
]
}
]
}
}
- Start a new Claude Code session
- Send any prompt (e.g., "hello")
- Check the captured file:
cat C:/temp/debug_hook_stdin.json
Expected: File contains JSON with hook input (e.g., {"session_id": "...", "cwd": "...", "prompt": "..."})
Actual: File is empty (0 bytes)
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.107
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗