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

There is no good reason to disable this. A hook command that omits ${CLAUDE_PLUGIN_ROOT} does not fire, and it fails silently: the plugin loads, the hook never runs, and no error is printed.

Resources

Version

Available since: v0.2.0