Skip to content

plugin-hook-missing-plugin-root

Inline hook commands must use ${CLAUDE_PLUGIN_ROOT} for portable script paths

Error

Rule Details

This rule checks inline hook definitions in plugin.json for command-type hooks that reference script files via relative paths. These commands must use ${CLAUDE_PLUGIN_ROOT} to form absolute paths that resolve correctly regardless of where the plugin is installed. String and array hook file paths are resolved by the plugin system and do not need this variable.

Incorrect

Inline hook command using a relative path without $

json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "My plugin",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "./scripts/post-tool.sh"
          }
        ]
      }
    ]
  }
}

Correct

Inline hook command using $

json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "My plugin",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-tool.sh"
          }
        ]
      }
    ]
  }
}

How To Fix

Replace relative script paths in inline hook commands with paths that start with ${CLAUDE_PLUGIN_ROOT}. For example, change ./scripts/lint.sh to ${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh.

Options

This rule does not have any configuration options.

When Not To Use It

This rule is off by default because inline hook objects in plugin.json are not yet supported at runtime by Claude Code. Only auto-discovered hooks from hooks/hooks.json currently work. Enable this rule if you are preparing plugins for future upstream support.

Resources

Version

Available since: v0.2.0