Clone
1
lessons/patterns/plugin-hooks-must-be-in-separate-file-not-inline
Leo Miranda edited this page 2026-01-25 20:45:10 +00:00

Plugin Hooks Must Be In Separate File - NOT Inline

Date: 2026-01-25 Impact: Plugin installation fails with "invalid input" errors Severity: CRITICAL - blocks plugin usage entirely

The Rule

NEVER put hooks in plugin.json. ALWAYS use separate hooks/hooks.json file.

Wrong (causes validation error)

In .claude-plugin/plugin.json:

"hooks": "hooks/hooks.json"
"hooks": { "SessionStart": [...] }

BOTH ARE WRONG. Any hooks field in plugin.json = invalid manifest.

Correct

  1. Remove ALL hooks from plugin.json
  2. Create hooks/hooks.json with this structure:
{
  "hooks": {
    "SessionStart": [
      {
        "type": "command",
        "command": "${CLAUDE_PLUGIN_ROOT}/hooks/startup-check.sh"
      }
    ]
  }
}

The file is AUTO-DISCOVERED. No reference needed in plugin.json.

Working Examples

  • projman: hooks/hooks.json exists, NO hooks in plugin.json
  • pr-review: hooks/hooks.json exists, NO hooks in plugin.json
  • claude-config-maintainer: hooks/hooks.json exists, NO hooks in plugin.json

Agents

Same rule: Do NOT add "agents": [...] to plugin.json. Agent .md files in agents/ directory are auto-discovered.

Checklist Before Commit

  1. plugin.json has NO hooks field
  2. plugin.json has NO agents field
  3. hooks/hooks.json exists if you need hooks
  4. Run ./scripts/validate-marketplace.sh
  5. ACTUALLY INSTALL AND TEST before merging

Tags: plugin-development, hooks, manifest, critical, validation-error