claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] SessionStart hooks never execute for local file-based marketplace plugins

Open kevincormier-toast opened this issue 2 months ago • 4 comments

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

SessionStart hooks (and likely all hooks) never execute when plugins are loaded from a local file-based marketplace. The issue appears to be that hooks are only discovered in ~/.claude/plugins/*/hooks/hooks.json, but local file-based marketplace plugins are referenced in-place and never copied to that directory.

Key observations:

  1. Plugin commands and skills work correctly (proving the plugin is loaded)
  2. Hook execution shows success message: SessionStart:Callback hook success: Success
  3. But the hook script output is never captured or provided to Claude's context
  4. The /hooks command does not list hooks from local marketplace plugins

This differs from issue #10997 which affects GitHub marketplace plugins where hooks fail on first run but work after caching. With local file marketplaces, hooks never work because there's no caching/copying step.

Environment

  • Claude Code Version: 2.0.37
  • Platform: macOS (Darwin 24.6.0)
  • Installation: CLI
  • Marketplace Type: Local file-based (in-repo)

What Should Happen?

Local file-based marketplace plugins should have full feature parity with GitHub marketplace plugins, including hook execution. The hooks system should:

  1. Discover hooks from plugins regardless of installation location
  2. Resolve ${CLAUDE_PLUGIN_ROOT} correctly for in-place plugins
  3. Execute hooks and capture their output
  4. List hooks in /hooks output

Error Messages/Logs


Steps to Reproduce

  1. Create a test plugin with a SessionStart hook

Create this directory structure: mkdir -p test-marketplace/test-plugin/{.claude-plugin,hooks,commands}

Create test-marketplace/.claude-plugin/marketplace.json: { "name": "test-marketplace", "owner": { "name": "Test", "email": "[email protected]" }, "metadata": { "description": "Test marketplace", "version": "1.0.0", "pluginRoot": "." }, "plugins": [ { "name": "test-plugin", "source": "./test-plugin", "description": "Test plugin with SessionStart hook", "version": "1.0.0", "author": { "name": "Test", "email": "[email protected]" } } ] }

Create test-marketplace/test-plugin/.claude-plugin/plugin.json: { "name": "test-plugin", "version": "1.0.0", "description": "Test plugin", "author": { "name": "Test", "email": "[email protected]" } }

Create test-marketplace/test-plugin/hooks/hooks.json: { "hooks": { "SessionStart": [ { "matcher": "startup", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/test-hook.sh" } ] } ] } }

Create test-marketplace/test-plugin/hooks/test-hook.sh: #!/bin/bash

cat <<'EOF' { "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "TEST HOOK EXECUTED: If you can see this message, the SessionStart hook is working." } } EOF

Make the script executable: chmod +x test-marketplace/test-plugin/hooks/test-hook.sh

Create a simple test command test-marketplace/test-plugin/commands/test.md:

name: test description: Test command to verify plugin is loaded

Reply with "Test plugin is loaded and working!"

  1. Install the marketplace and plugin

cd test-marketplace claude /plugin marketplace add . claude /plugin install test-plugin@test-marketplace

  1. Verify plugin is loaded (commands work)

claude /test

Expected: Should see "Test plugin is loaded and working!" Actual: ✅ This works - confirms plugin is loaded

  1. Test if SessionStart hook executes

Start a new Claude session: claude

Then ask Claude: "Can you see any test hook message in your context?"

Expected: Claude should see the "TEST HOOK EXECUTED" message in its context Actual: ❌ Claude has no such message in context

  1. Verify hook is not registered

In the Claude session, run: /hooks

Expected: Should list the SessionStart hook from test-plugin Actual: ❌ Hook is not listed

  1. Verify hook script works when run directly

bash test-marketplace/test-plugin/hooks/test-hook.sh

Expected: Should output valid JSON Actual: ✅ Outputs valid JSON correctly


This shows that:

  • The plugin loads (commands work)
  • The hook script is valid (runs correctly when executed directly)
  • But the hook is never discovered or executed by Claude Code

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.0.37

Platform

AWS Bedrock

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Related Issues

  • #10997 - SessionStart hooks don't execute on first run with GitHub marketplace plugins (different - affects only first run, not all runs)
  • #9354 - ${CLAUDE_PLUGIN_ROOT} variable issues (related but different)
  • #10871 - Plugin-registered hooks executed twice (affects working plugin hooks)

Workaround

Temporarily register hooks globally in ~/.config/claude/hooks/hooks.json with absolute paths to the plugin scripts. However, this defeats the purpose of plugin-based hooks and doesn't scale for distributed plugins.

Impact

This prevents developers from:

  • Building plugins with hooks in local development environments
  • Distributing plugins via file-based marketplaces with hook functionality
  • Testing hook behavior before publishing to GitHub marketplaces

kevincormier-toast avatar Nov 12 '25 21:11 kevincormier-toast

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/9354
  2. https://github.com/anthropics/claude-code/issues/11243
  3. https://github.com/anthropics/claude-code/issues/10113

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

github-actions[bot] avatar Nov 12 '25 21:11 github-actions[bot]

Closed as dup, but just incase there are helpful details, linking here: https://github.com/anthropics/claude-code/issues/11939

zerobearing2 avatar Nov 19 '25 15:11 zerobearing2

experiencing this with 2.0.55 on Ubuntu too

ihanikos avatar Dec 01 '25 08:12 ihanikos

Experiencing the same on 2.0.73 on Ubuntu 24 via WSL and Claude Code Web.

This seems to be an issue related to upgrading beyond 2.0.70. To fix, uninstall all plugins and clear prior installation from plugin cache at ~/.claude/plugins/cache and then reinstall the plugins freshly and they should work. Note I also updated to 2.0.74 before starting the next session.

https://github.com/anthropics/claude-code/issues/12634#issuecomment-3674215064 https://github.com/anthropics/claude-code/issues/14410

sylvansys avatar Dec 19 '25 22:12 sylvansys