[BUG] SessionStart hooks never execute for local file-based marketplace plugins
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:
- Plugin commands and skills work correctly (proving the plugin is loaded)
- Hook execution shows success message:
SessionStart:Callback hook success: Success - But the hook script output is never captured or provided to Claude's context
- The
/hookscommand 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:
- Discover hooks from plugins regardless of installation location
- Resolve ${CLAUDE_PLUGIN_ROOT} correctly for in-place plugins
- Execute hooks and capture their output
- List hooks in /hooks output
Error Messages/Logs
Steps to Reproduce
- 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!"
- Install the marketplace and plugin
cd test-marketplace claude /plugin marketplace add . claude /plugin install test-plugin@test-marketplace
- Verify plugin is loaded (commands work)
claude /test
Expected: Should see "Test plugin is loaded and working!" Actual: ✅ This works - confirms plugin is loaded
- 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
- 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
- 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
Found 3 possible duplicate issues:
- https://github.com/anthropics/claude-code/issues/9354
- https://github.com/anthropics/claude-code/issues/11243
- 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
Closed as dup, but just incase there are helpful details, linking here: https://github.com/anthropics/claude-code/issues/11939
experiencing this with 2.0.55 on Ubuntu too
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