Skip to content

Hook executor doesn't set CLAUDE_PLUGIN_ROOT environment variable #24529

@rexplx

Description

@rexplx

Hook executor doesn't set CLAUDE_PLUGIN_ROOT environment variable

Summary

Plugin hooks that use ${CLAUDE_PLUGIN_ROOT} fail with "Cannot find module" errors because the hook execution system doesn't set this environment variable before running hooks.

Reproduction

  1. Install plugin with hooks using ${CLAUDE_PLUGIN_ROOT} (e.g., claude-mem, claude-reflect)
  2. Enable the plugin: claude plugin enable claude-mem
  3. Execute any tool or submit a prompt
  4. Observe hook errors in logs/TLDR

Expected Behavior

Hook executor should:

  1. Parse ${CLAUDE_PLUGIN_ROOT} placeholder in hook commands
  2. Set environment variable to plugin's cache directory path
  3. Substitute/expand the variable before execution

Similar to how ${CLAUDE_PROJECT_DIR} is handled.

Actual Behavior

  • ${CLAUDE_PLUGIN_ROOT} remains unexpanded
  • Scripts try to execute from /scripts/... (absolute root path)
  • Error: Cannot find module '/scripts/bun-runner.js'

Evidence

Plugin hook definition:

{
  "PostToolUse": [{
    "matcher": "*",
    "hooks": [{
      "type": "command",
      "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/bun-runner.js\" ..."
    }]
  }]
}

Environment check:

$ env | grep CLAUDE
CLAUDE_PROJECT_DIR=/Users/.../project  ✅ SET
CLAUDE_PLUGIN_ROOT=                     ❌ NOT SET

Manual verification:

# Fails without variable
$ node "/scripts/bun-runner.js"
Error: Cannot find module '/scripts/bun-runner.js'

# Works with variable set
$ export CLAUDE_PLUGIN_ROOT="$HOME/.claude/plugins/cache/thedotmack/claude-mem/9.1.1"
$ node "${CLAUDE_PLUGIN_ROOT}/scripts/bun-runner.js"
✅ Success

Affected Plugins

  • claude-mem@thedotmack (v9.1.1)
  • claude-reflect@claude-reflect-marketplace (v2.5.1)
  • Any plugin using ${CLAUDE_PLUGIN_ROOT} in hooks

Impact

  • ❌ PostToolUse observation tracking broken
  • ❌ UserPromptSubmit hooks broken
  • ❌ SessionStart hooks broken
  • ⚠️ Hook errors spam logs but don't break core functionality
  • ⚠️ MCP tools from plugins still work (different mechanism)

Environment

  • OS: macOS (Darwin 25.3.0)
  • Claude Code: Latest as of 2026-02-09
  • Plugins installed: claude-mem 9.1.1, claude-reflect 2.5.1

Additional Context

This appears to be a regression or missing feature in the hook execution system. Other environment variables like ${CLAUDE_PROJECT_DIR} work correctly, suggesting the infrastructure exists but ${CLAUDE_PLUGIN_ROOT} isn't included.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corearea:toolsbugSomething isn't workinghas reproHas detailed reproduction stepsplatform:macosIssue specifically occurs on macOSstaleIssue is inactive

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions