[BUG] Windows: ${CLAUDE_PLUGIN_ROOT} left unexpanded in Claude Desktop (Cowork), PreToolUse Bash hook fully blocked

Resolved 💬 2 comments Opened Jun 5, 2026 by aozoraimura-crypto Closed Jun 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Windows: plugin hook ${CLAUDE_PLUGIN_ROOT} left unsubstituted in
Claude Desktop (Cowork), breaking PreToolUse Bash hooks
Related: #39550 (canonical, closed, macOS), #43380, #18527 — this is the Windows manifestation with blocking (non-cosmetic) severity

Environment:

  • Claude Desktop (Cowork), latest, Windows 11
  • Python 3.14
  • Org-managed (remote) plugins with PreToolUse Bash hooks

Symptom:
Running a Bash tool call fails. The hook command is shell form:
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-bash.py"
and produces:
python.exe: can't open file
'...\outputs\${CLAUDE_PLUGIN_ROOT}\hooks\scripts\check-bash.py':
[Errno 2] No such file or directory

Root cause:
On Windows, ${CLAUDE_PLUGIN_ROOT} is NOT substituted before the hook
subprocess is spawned. The literal string "${CLAUDE_PLUGIN_ROOT}" is
passed through and resolved relative to the session cwd, so the file
is never found. This matches #43380 (CLAUDE_PLUGIN_ROOT not injected
at hook execution time) and #11984 (portability). Related backslash-
handling variants on Windows: #18527, #22449, #23204.

Request:
Substitute ${CLAUDE_PLUGIN_ROOT} as a plain string into command/args
before spawning on Windows (as documented for exec form), and ensure
the path is correct for the target shell.

Note: a .sh-based hook in the same plugin also fails on Windows
(cannot be spawned directly); cf. #21847.

What Should Happen?

Expected Behavior:
${CLAUDE_PLUGIN_ROOT} should be substituted to the plugin's actual
installation directory before the hook subprocess is spawned on
Windows — the same as on macOS/Linux — so the hook script is found
and runs.

Concretely:

  • The literal string "${CLAUDE_PLUGIN_ROOT}" must never reach the

spawned process unexpanded.

  • The substituted path must be in a form the target interpreter/shell

can resolve on Windows (handle backslashes and spaces in the path).

  • This should hold for both shell form and exec form, and regardless

of the interpreter (python3, node, bash, etc.).

  • Result: the PreToolUse Bash hook runs without error and the Bash

tool is usable on Windows.

Error Messages/Logs

PreToolUse:mcp__workspace__bash hook error: 
[python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-bash.py]: 
C:\Users\...\AppData\Local\Python\pythoncore-3.14-64\python.exe: 
can't open file 
'C:\Users\...\AppData\Roaming\Claude\local-agent-mode-sessions\
...\outputs\${CLAUDE_PLUGIN_ROOT}\hooks\scripts\check-bash.py': 
[Errno 2] No such file or directory

Steps to Reproduce

Steps to Reproduce:

Environment: Windows 11, Claude Desktop (Cowork), latest.

  1. Create a minimal plugin with a PreToolUse Bash hook in SHELL form

(no "args"), referencing the placeholder. hooks/hooks.json:

{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash",
"hooks": [
{ "type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-bash.py" }
] }
]
}
}

  1. Add the referenced script so the path is valid when expanded:

hooks/scripts/check-bash.py -> print("ok")

  1. Install/enable the plugin in Claude Desktop (Cowork) on Windows.
  1. In a session, trigger any Bash tool call.

Observed:
python.exe: can't open file
'...\outputs\${CLAUDE_PLUGIN_ROOT}\hooks\scripts\check-bash.py':
[Errno 2] No such file or directory

-> "${CLAUDE_PLUGIN_ROOT}" is left literal and resolved relative to
the session cwd; the file is never found and the Bash tool is blocked.

Notes:

  • Same hooks.json works on macOS/Linux.
  • Reproduces regardless of whether the user profile path contains a

space (a space makes it worse; cf. path tokenization).

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Claude 1.11187.1 (370d3b) 2026-06-04T17:30:35.000Z

Platform

Other

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

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