Windows: Plugin stop hook paths break due to backslash expansion in CLAUDE_PLUGIN_ROOT

Resolved 💬 3 comments Opened Feb 12, 2026 by Relayer5521 Closed Feb 15, 2026

Bug

Stop hook paths on Windows have backslashes stripped when passed to bash.

Environment

  • Claude Code: 2.1.39
  • OS: Windows 11 Pro 10.0.26220
  • Shell: Git Bash (/bin/bash)
  • Plugin: ralph-loop (from claude-plugins-official marketplace)

What happens

Plugin hooks use ${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh in hooks.json. On Windows, Claude Code expands CLAUDE_PLUGIN_ROOT to a native Windows path with backslashes (e.g. C:\Users\rr\.claude\plugins\cache\claude-plugins-official\ralph-loop\2cd88e7947b7). When this is concatenated and passed to /bin/bash (Git Bash), the backslashes are interpreted as escape characters, breaking the path.

Expected behavior

Claude Code should normalize CLAUDE_PLUGIN_ROOT to forward slashes before invoking the command, or use the bash-compatible path format (e.g. C:/Users/rr/.claude/plugins/cache/...).

Reproduction

  1. Install the ralph-loop plugin from claude-plugins-official on Windows
  2. The plugin's hooks.json registers a stop hook:

``json
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh"
}]
}]
}
}
``

  1. The hook errors on session stop because the expanded path contains unescaped backslashes

Workaround

None available from the plugin side — the variable is expanded at runtime by Claude Code. The hook script itself works correctly when invoked with forward-slash paths:

# This works:
bash "C:/Users/rr/.claude/plugins/cache/.../hooks/stop-hook.sh"

# This breaks (what Claude Code generates):
bash "C:\Users\rr\.claude\plugins\cache\...\hooks\stop-hook.sh"

Notes

This likely affects all plugin hooks on Windows that use ${CLAUDE_PLUGIN_ROOT} in their command paths, not just ralph-loop.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗