Plugin hooks fail on Windows: CLAUDE_PLUGIN_ROOT expands with backslashes

Resolved 💬 3 comments Opened Feb 17, 2026 by gabrieImoreira Closed Feb 17, 2026

Bug Description

Plugin stop hooks fail on Windows because the ${CLAUDE_PLUGIN_ROOT} environment variable is expanded using Windows-style backslashes (\), which are interpreted as escape characters by bash. This causes the hook script path to be unresolvable.

Error Message

Stop hook error: Failed with non-blocking status code:
/bin/bash: C:Usersgabri.claudepluginscacheclaude-plugins-officialralph-loop2cd88e7947b7/hooks/stop-hook.sh: No such file or directory

Note how all backslashes are stripped: C:\Users\gabri\.claude\... becomes C:Usersgabri.claude....

Expected Behavior

${CLAUDE_PLUGIN_ROOT} should be expanded using forward slashes (/) when the configured shell is bash (Git Bash / MSYS2), e.g.:

/c/Users/gabri/.claude/plugins/cache/claude-plugins-official/ralph-loop/2cd88e7947b7/hooks/stop-hook.sh

The file exists and is executable at the Unix-style path — the issue is purely in the variable expansion.

Hook Configuration (from plugin)

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

Environment

  • OS: Windows 11 (10.0.26200)
  • Shell: GNU bash 5.2.37 (Git Bash / MSYS2)
  • Claude Code: Latest (as of Feb 2026)
  • Plugin: ralph-loop@claude-plugins-official (commit 2cd88e7947b7)

Reproduction Steps

  1. Install Claude Code on Windows with bash (Git Bash) as the configured shell
  2. Install a plugin that uses hooks with ${CLAUDE_PLUGIN_ROOT} (e.g. ralph-loop)
  3. Run any command that triggers the hook (e.g. complete a session to trigger the Stop hook)
  4. Observe the "No such file or directory" error with stripped backslashes

Suggested Fix

When expanding ${CLAUDE_PLUGIN_ROOT} for hook commands, normalize the path to use forward slashes if the target shell is bash. Something like:

pluginRoot = pluginRoot.replace(/\\/g, '/');
// Also convert drive letter: C:/ → /c/
pluginRoot = pluginRoot.replace(/^([A-Za-z]):\//, '/$1/');

This would make the expanded path compatible with Git Bash / MSYS2 on Windows while remaining valid on macOS/Linux.

View original on GitHub ↗

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