CLAUDE_PLUGIN_ROOT inconsistent between hooks/skills and agent environment for local marketplace plugins

Resolved 💬 6 comments Opened Mar 25, 2026 by cowwoc Closed Apr 8, 2026

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

  1. Create a local marketplace with source pointing to a plugin directory:

``json
// .claude-plugin/marketplace.json
{
"name": "my-marketplace",
"owner": { "name": "example" },
"plugins": [
{
"name": "my-plugin",
"source": "./plugin",
"description": "Example plugin"
}
]
}
``

  1. Install the plugin: claude plugin install my-marketplace@my-plugin
  2. Verify installed_plugins.json shows installPath pointing to the cache directory
  3. In a hook script, log $CLAUDE_PLUGIN_ROOT — it shows the source directory (e.g., /workspace/plugin)
  4. 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.

View original on GitHub ↗

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