Summary
The Claude Code stop hook (mempalace-stop.js) hangs indefinitely on Windows at session end. The spinner shows running stop hooks… 3/3 and blocks for minutes (observed: 4m 41s+) before the session closes.
Root Cause
The final process.stdout.write() call in mempalace-stop.js does not pass a callback with process.exit(0). On Windows, Node.js holds the event loop open after a spawn() call — even with detached: true and child.unref() — because the stdout pipe is not flushed synchronously. The process never exits.
Steps to Reproduce
- Install the mempalace Claude Code plugin on Windows
- Run any Claude Code session long enough for the stop hook to fire (no cooldown active)
- End the session (
/clear, close, or Ctrl+C)
- Observe: spinner shows
running stop hooks… 3/3 and hangs for minutes
Fix
Change the final stdout.write call from:
process.stdout.write(JSON.stringify({ systemMessage: '...' }));
to:
process.stdout.write(JSON.stringify({ systemMessage: '...' }), () => process.exit(0));
The callback fires after the write is flushed, then exits immediately. This is the correct pattern for Node.js CLI scripts that write JSON to stdout and must exit cleanly.
Also recommended: add "timeout": 10 to the Stop hook entry in the plugin's settings.json template as a hard backstop against any future regressions.
Environment
- OS: Windows 11 Pro 10.0.26200
- Shell: bash (Git Bash)
- Node.js: system node
- Claude Code: latest
- mempalace: latest
Workaround (applied locally)
Applied both fixes manually:
- Edited
~/.claude/hooks/mempalace-stop.js to use the callback form
- Added
"timeout": 10 to the Stop hook in ~/.claude/settings.json
Summary
The Claude Code stop hook (
mempalace-stop.js) hangs indefinitely on Windows at session end. The spinner showsrunning stop hooks… 3/3and blocks for minutes (observed: 4m 41s+) before the session closes.Root Cause
The final
process.stdout.write()call inmempalace-stop.jsdoes not pass a callback withprocess.exit(0). On Windows, Node.js holds the event loop open after aspawn()call — even withdetached: trueandchild.unref()— because the stdout pipe is not flushed synchronously. The process never exits.Steps to Reproduce
/clear, close, or Ctrl+C)running stop hooks… 3/3and hangs for minutesFix
Change the final
stdout.writecall from:to:
The callback fires after the write is flushed, then exits immediately. This is the correct pattern for Node.js CLI scripts that write JSON to stdout and must exit cleanly.
Also recommended: add
"timeout": 10to the Stop hook entry in the plugin's settings.json template as a hard backstop against any future regressions.Environment
Workaround (applied locally)
Applied both fixes manually:
~/.claude/hooks/mempalace-stop.jsto use the callback form"timeout": 10to the Stop hook in~/.claude/settings.json