[BUG] SessionStart hook spawning powershell.exe permanently disables keyboard input in Claude Code TUI on Windows
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?
On Windows, when a SessionStart hook that invokes powershell.exe is registered in settings.json, Claude Code's TUI renders successfully but keyboard input is completely non-functional after startup. The cursor is visible in the input field, but no keystrokes are registered — not even after waiting several minutes. The only fix is removing all hooks from settings.json.
What Should Happen?
CC should work in Windows Terminal/Powershell, so i can type also when there are powershell commands in project directories.****
Error Messages/Logs
Debug Log Evidence
Startup completes normally. All expected entries are logged:
[STARTUP] Running showSetupScreens()...
[STARTUP] showSetupScreens() completed in 502ms
[LSP MANAGER] initializeLspServerManager() called
Getting matching hook commands for SessionStart with query: startup
Matched 1 unique hooks for query "startup"
Hook output does not start with {, treating as plain text ← hook ran & exited
[REPL:mount] REPL mounted, disabled=false ← REPL enabled
MCP server "plugin:playwright:playwright": Successfully connected in 1045ms
After startup completes (~2.4s), no further debug events are ever logged — even though the session remains open and the TUI is visually intact. This suggests the event loop is still running (status line updates correctly) but stdin is no longer in raw mode.
Steps to Reproduce
Steps to Reproduce
- Add a SessionStart hook to ~/.claude/settings.json that invokes powershell.exe:
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File \"C:\\path\\to\\hook.ps1\"",
"timeout": 10
}]
}]
}
- Create a project directory with .claude/settings.local.json containing:
{
"permissions": {
"allow": ["Bash(powershell.exe:*)"]
}
}
- Open a terminal in that project directory
- Run claude
Result: CC starts, the TUI renders, but no keyboard input works — permanently.
Does NOT reproduce in: directories without Bash(powershell.exe:*) in project-level settings.
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.37 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Environment
- OS: Windows 11
- Claude Code: v2.1.37
- Terminal: Windows Terminal with PowerShell 7.5.4
- Trigger: Installing https://github.com/PeonPing/peon-ping/— a sound notification plugin that registers PowerShell-based hooks
Root Cause Hypothesis
When Node.js spawns powershell.exe as a child process on Windows, the spawned process modifies the Windows Console Input Mode (via SetConsoleMode). When PowerShell exits, it leaves the console in a non-raw (cooked/line-buffered) mode. Claude Code does not restore raw mode after the hook completes, leaving the terminal unable to deliver individual keystrokes to the CC process.
This is specific to project directories with Bash(powershell.exe:*) because this permission appears to control whether hooks that invoke powershell.exe are actually executed vs. silently skipped in a given directory context.
Workaround
Remove all hooks using powershell.exe from ~/.claude/settings.json (or clear the hooks section entirely). This fully restores keyboard input.
Alternatively, removing Bash(powershell.exe:*) from project-level settings may prevent hook execution in that
directory.
Notes
- Setting enabled: false in the hook's own config does not fix the issue if the PowerShell process is still spawned
(even briefly)
- The bug is not terminal emulator specific — it likely affects any Windows terminal
- This is likely reproducible for any Windows user who has (1) a PowerShell-based hook and (2) Bash(powershell.exe:*) in a project's .claude/settings.local.json
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗