CLAUDE_PLUGIN_ROOT inconsistent between hooks/skills and agent environment for local marketplace plugins
Bug Description
When a plugin is installed from a local marketplace (claude plugin install cat@cat), CLAUDE_PLUGIN_ROOT is set to two different values depending on the context:
| Context | CLAUDE_PLUGIN_ROOT |
|---|---|
| Hooks (e.g., session-start.sh) | /workspace/plugin (source directory) |
| Skill preprocessor directives (${CLAUDE_PLUGIN_ROOT}) | /workspace/plugin (source directory) |
| Agent Bash environment (echo $CLAUDE_PLUGIN_ROOT) | ~/.config/claude/plugins/cache/cat/cat/2.1 (cache/install directory) |
Expected Behavior
CLAUDE_PLUGIN_ROOT should consistently point to the installation directory (the installPath from installed_plugins.json) in all contexts — hooks, skill preprocessor directives, and the agent's shell environment.
Actual Behavior
Hooks and skill preprocessor directives receive the source directory from the marketplace definition, while the agent's Bash environment receives the cache/install directory. This causes skills that reference ${CLAUDE_PLUGIN_ROOT}/client/bin/... to fail with "no such file or directory" because compiled binaries exist in the cache but not in the source tree.
Steps to Reproduce
- Create a local marketplace with
sourcepointing to a plugin directory:
``json``
// .claude-plugin/marketplace.json
{
"name": "my-marketplace",
"owner": { "name": "example" },
"plugins": [
{
"name": "my-plugin",
"source": "./plugin",
"description": "Example plugin"
}
]
}
- Install the plugin:
claude plugin install my-marketplace@my-plugin - Verify
installed_plugins.jsonshowsinstallPathpointing to the cache directory - In a hook script, log
$CLAUDE_PLUGIN_ROOT— it shows the source directory (e.g.,/workspace/plugin) - In the agent's Bash tool, run
echo $CLAUDE_PLUGIN_ROOT— it shows the cache directory
Evidence
Debug output from a session-start hook:
script_dir=/workspace/plugin/hooks
BASH_SOURCE[0]=/workspace/plugin/hooks/session-start.sh
CLAUDE_PLUGIN_ROOT (raw)=/workspace/plugin
installed_plugins.json entry:
{
"installPath": "/home/node/.config/claude/plugins/cache/cat/cat/2.1",
"version": "2.1"
}
Agent Bash environment:
CLAUDE_PLUGIN_ROOT=/home/node/.config/claude/plugins/cache/cat/cat/2.1
Impact
Any skill using ${CLAUDE_PLUGIN_ROOT} in preprocessor directives to locate compiled binaries or other non-source artifacts fails when the plugin is installed from a local marketplace, because the preprocessor resolves the variable to the source directory where those artifacts don't exist.
Environment
- Claude Code CLI (Version 2.1.83)
- Linux (WSL2)
This is a regression. Version 2.1.81 works as expected.
This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗