[BUG] Windows hook commands with backslash paths silently never execute (bash eats the backslashes) — killed my memory hooks for 46 days
Summary
On Windows, a hook command containing Windows-style backslash paths never executes. Claude Code runs hook commands through Git Bash, which consumes the backslashes as escape characters. Because non-blocking hooks fail open with no surfaced error, the hook is silently dead — potentially for months — while the user sees only degraded behavior with no indication of a misconfiguration.
On my machine this silently disabled my entire persistent-memory setup (SessionStart + UserPromptSubmit + PostToolUse) for 46 days, from 2026-07-06 until I went looking on 2026-08-21. Nothing anywhere reported a problem.
This is the same class as #61922 (tilde not expanded → global UserPromptSubmit hook silently fails), which was accepted and fixed. The trigger differs; the silent-failure outcome is identical.
Reproduction
~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "C:\\path\\to\\python.exe C:\\project\\.claude\\hooks\\my_hook.py",
"timeout": 6
}
]
}
]
}
}
Start a session and submit a prompt.
Expected: the hook runs, or a visible error explains why it did not.
Actual: nothing happens. No output, no warning, no indicator. The hook never executed.
Reproduced directly in the same shell Claude Code uses:
$ echo '{"session_id":"t"}' | C:\path\to\python.exe C:\project\.claude\hooks\my_hook.py
/usr/bin/bash: line 1: C:pathtopython.exe: command not found
Bash strips every \, so C:\path\to\python.exe becomes C:pathtopython.exe.
The identical hook works when written with quoted forward slashes:
"command": "\"C:/path/to/python.exe\" \"C:/project/.claude/hooks/my_hook.py\""
Why this is hard for a user to find
- The path in
settings.jsonis a perfectly valid Windows path. It looks correct to any Windows user, and to every Windows tool other than the hook launcher. - Non-blocking hooks fail open with no surfaced error.
- Nothing indicates a hook was configured but never fired.
- In my case one hook in the same file (
rtk hook claude) kept working, because it contains no backslashes. So the feature appeared partly functional, which pointed away from a systemic cause.
I only diagnosed it by noticing my hook's own log file had no entries for six weeks. Without that self-written log there was no signal at all.
Impact
Silent hook death degrades exactly the features people configure hooks for — context injection, memory, guardrails — while giving the user no way to attribute the degradation. My conclusion for six weeks was "Claude keeps forgetting things," not "a hook is misconfigured." Users in that position tend not to file bugs; they conclude the capability does not work and install third-party replacements.
This is also the second occurrence of this class on my machine. An earlier one (2026-04-15) had a different trigger — a cmd /c "set VAR=x&& ..." wrapper mis-parsed by the launcher — and produced the same invisible failure.
Suggested fixes, in priority order
- Surface non-blocking hook failures. If a hook's command exits non-zero or is not found, show it — a one-line session notice, or a status indicator. Silence is the core problem. A hook that has never once succeeded is almost certainly misconfigured rather than intentionally inert.
- Validate hook commands at config load. Resolve the executable at session start and warn if it does not exist, instead of failing invisibly on every invocation.
- Document the shell contract. The docs do not state that hook commands run through Git Bash on Windows, which makes backslash paths a trap. Either document "use forward slashes" prominently, or normalize drive-letter paths before execution.
- Provide a hook health check. Something like
claude doctor --hooksthat executes each configured hook and reports dead ones. I ended up writing my own to find this, which is not a reasonable expectation.
Item 1 alone would have turned a 46-day outage into a 5-second fix.
Environment
- Claude Code desktop app, Windows 11 Pro 26200
- Git Bash at
C:\Program Files\Git\bin\bash.exe - Hooks configured in
~/.claude/settings.json
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗