Windows: Plugin hooks using ${CLAUDE_PLUGIN_ROOT} fail to start
Bug Description
On Windows, plugin hooks that use ${CLAUDE_PLUGIN_ROOT} in their command fail with:
Plugin hook "C:\Users\...\hooks\stop-hook.sh" failed to start: The operation was aborted.
Steps to Reproduce
- Install a plugin with hooks (e.g.,
ralph-wiggum@claude-plugins-official) - Plugin's
hooks/hooks.jsoncontains:
``json``
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh"
}]
}]
}
}
- Trigger the stop hook (end a session)
- Error appears: "failed to start: The operation was aborted"
Expected Behavior
The ${CLAUDE_PLUGIN_ROOT} variable should expand to the plugin's cached directory path and the hook should execute.
Actual Behavior
The variable doesn't expand correctly on Windows. The hook runner appears to abort before starting the command.
Workaround
Manually edit the cached plugin's hooks.json to use explicit bash with full path:
{
"command": "bash C:/Users/USERNAME/.claude/plugins/cache/claude-plugins-official/plugin-name/HASH/hooks/stop-hook.sh"
}
Or register the hook directly in project .claude/settings.json with a relative path:
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "bash .claude/plugins/plugin-name/hooks/stop-hook.sh"
}]
}]
}
}
Environment
- OS: Windows 11 (MINGW64_NT-10.0-26200)
- Shell: Git Bash
- Claude Code: Latest CLI version
- Plugin: ralph-wiggum@claude-plugins-official
Suggested Fix
- Ensure
${CLAUDE_PLUGIN_ROOT}is expanded before passing to the shell - Use Unix-style paths (forward slashes) on Windows for bash compatibility
- Prepend
bashto.shcommands automatically on Windows
Additional Context
The hook script itself runs fine when called directly:
echo '{}' | bash "/path/to/stop-hook.sh" # Works
The issue is in the hook runner's command construction/execution on Windows.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗