Plugin-sourced hooks.json never fires, even though the plugin shows installed + enabled (no error, no registry entry evidence)
Claude Code version: 2.1.202 (macOS/Darwin)
Summary: A plugin's hooks.json (SessionStart, Stop, PreToolUse, PostToolUse, PreSkill hooks) never fires, despite the plugin being installed, enabled, and its cached hooks.json matching the source repo exactly. The plugin's skills/agents work normally — only the hooks are silently inert.
Setup (verified correct):
- Plugin
base-tools@claude-baseappears in~/.claude/plugins/installed_plugins.json(auto-installed as a dependency of another plugin,scope: user,auto: true) - Explicitly enabled in
~/.claude/settings.json→"enabledPlugins": {"base-tools@claude-base": true} - Cached
hooks.jsonis byte-identical to the plugin source, with standard${CLAUDE_PLUGIN_ROOT}/hooks/*.shcommand entries forSessionStart,Stop,PostToolUse(matcherWrite|Edit), 8xPreToolUse(matchersBash,Write|Edit), andPreSkill(matcher.*) - All hook scripts present on disk, correct executable permissions
Evidence they don't fire:
- Live repro: ran
echo test --no-verifyvia the Bash tool. APreToolUse/Bashhook in this plugin blocks any command containing--no-verify(exit 2 + stderr message). The command executed cleanly with no block. - A
PreSkillhook writes one JSON line per skill activation to${CLAUDE_PLUGIN_DATA}/base-tools/skills.jsonl. That file does not exist anywhere on disk despite many skill invocations across 11 sessions in the project. - Checked raw session transcripts (
~/.claude/projects/.../*.jsonl) for all 11 sessions in the project -- theSessionStarthook is supposed to inject a short primer into context. In every session, the first user message appears immediately after themode/permission-mode/file-history-snapshotbootstrap entries with zero injected content in between. - No
Stop-hook output appears at the end of a completed session (only aturn_durationsystem marker).
Expected: Hooks registered in an enabled plugin's hooks.json should fire per the documented hook-dispatch behavior -- no additional trust/approval step or restart is documented as required beyond install + enable.
Question: Does a plugin that is only transitively installed as a dependency (auto: true in installed_plugins.json, pulled in via another plugin's dependencies field) get its hooks.json registered into the session's hook dispatch the same way a directly-installed plugin does? That's the one structural difference here vs. a normal install, and it's not covered in the plugin hooks docs.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗