[Windows] SessionStart hooks cause infinite hang during initialization
Environment
- OS: Windows 10/11
- Claude Code Version: Latest (as of 2025-10-14)
- Node.js Version: Any
- Hook Type: SessionStart with matchers
- Platform Comparison: macOS ✅ Works | Linux ✅ Works (assumed) | Windows ❌ Hangs
Problem Description
SessionStart hooks cause Claude Code to become completely unresponsive on Windows during initialization. The hook subprocess executes and exits successfully, but Claude Code never detects the completion and hangs indefinitely. This requires force-closing the terminal to recover.
Root Cause Analysis
After extensive investigation, I've identified this as a Windows-specific subprocess lifecycle management bug in Claude Code's initialization phase:
The Deadlock Mechanism
┌─ Claude Code Initialization (Windows) ─┐
│ 1. Start synchronous initialization │
│ 2. Spawn SessionStart hook subprocess │
│ 3. **BLOCK** waiting for completion │ ← Stuck here forever
│ 4. Enter event loop (NEVER REACHED) │
└────────────────────────────────────────┘
↓
┌─ Hook Subprocess ───────────────────────┐
│ 1. Execute code │
│ 2. process.exit(0) successfully │
│ 3. Send exit signal to parent │
└─────────────────────────────────────────┘
↓
┌─ Parent Process ────────────────────────┐
│ ❌ Still in sync initialization block │
│ ❌ NOT polling subprocess status │
│ ❌ Exit signal queued but unprocessed │
└─────────────────────────────────────────┘
Why Windows is Different
Unix/Linux/macOS: Async signals (kqueue/epoll) delivered even during blocking → hooks work ✅
Windows: Requires active polling of subprocess handles → sync init doesn't poll → signals never processed ❌
Minimal Reproduction
session-start-minimal.js:
// Literally just exit - no logic, no I/O
console.log('Starting');
process.exit(0);
settings.json:
{
"hooks": {
"SessionStart": [{
"matchers": ["*"],
"hooks": [{
"type": "command",
"command": "node session-start-minimal.js",
"timeout": 5000
}]
}]
}
}
Steps:
- Save files above
- Run
claudein any directory - Result: Infinite hang, cannot type prompts, Ctrl+C doesn't work
Critical Discovery
Even a hook that ONLY calls process.exit(0) with zero logic still hangs. This proves:
- ❌ NOT a hook code issue
- ❌ NOT a timeout issue
- ❌ NOT a cleanup issue
- ✅ IS a subprocess invocation issue during initialization
Failed Solution Attempts
Tried 5 different approaches:
- Force process.exit() - Hook exits, parent still hangs
- Wrapper functions - Same result
- Batch file wrapper - Parent waits for wrapper AND children
- PowerShell Start-Process - Job objects prevent true detachment
- File-based trigger - Even 10ms hooks cause hang
None work because Windows requires active polling, and sync init doesn't poll.
Why UserPromptSubmit/SessionEnd Work
These hooks execute AFTER initialization when:
- Event loop is running
- Parent actively polls subprocess status
- Exit signals are properly detected
Impact
- Severity: Critical - Complete feature loss for Windows users
- Affected Users: All Windows users with SessionStart hooks
- Workaround: Disable SessionStart, use UserPromptSubmit instead
Requested Fix
Option 1 (Recommended): Move SessionStart hooks to async initialization phase (after event loop starts)
Option 2: Add active subprocess polling during sync init on Windows
Option 3: Add timeout enforcement with force-kill
Option 4: Document limitation and skip SessionStart on Windows
Additional Context
- Detailed Analysis: https://github.com/doobidoo/mcp-memory-service/blob/main/claude-hooks/WINDOWS-SESSIONSTART-BUG.md
- Project: MCP Memory Service with memory-aware session hooks
- Discovery: Found while implementing automatic memory context injection
This is a platform-specific issue that cannot be fixed at the hook level and requires changes to Claude Code's subprocess management on Windows.
7 Comments
Related Project Issue
This issue was discovered while implementing memory-aware session hooks for the MCP Memory Service project.
Related Issue: https://github.com/doobidoo/mcp-memory-service/issues/160
The project issue contains:
Both issues are tracking the same bug from different perspectives:
Just noting you can unblock and continue to use claude-code by pressing Enter/Return twice, as per https://github.com/anthropics/claude-code/issues/7755#issuecomment-3303271284
I see this too when I send a prompt at the exact same time claude finishes if I have a stop hook enabled.
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
✅ Confirmed Fixed in Claude Code 2.0.76
Test Environment:
Test Methodology:
Result: ✅ Both hooks execute correctly without hanging
The subprocess lifecycle management issue appears to be resolved in Claude Code 2.0.76. SessionStart hooks with
matchers: ["*"]now work correctly on Windows.Configuration that now works:
Thank you for the fix! 🎉
Closing as fixed in Claude Code 2.0.76. SessionStart hooks now work correctly on Windows.
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.