[BUG] Misleading "duplicate hooks" warning for marketplace-installed 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?
Claude Code displays a "duplicate hooks file detected" warning for marketplace-installed plugins, claiming that hooks/hooks.json is loaded automatically. However, this is false for marketplace installations - hooks do NOT auto-load without explicit manifest registration. This causes plugin developers to remove the registration (trusting the warning), which silently breaks their plugins.
What Should Happen?
Hooks should auto-load for marketplace installations (making the warning accurate)
Currently, marketplace-installed plugins REQUIRE "hooks": "./hooks/hooks.json" in their manifest for hooks to work, despite the warning claiming this creates a duplicate.
Error Messages/Logs
Hook load failed: Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file
[...]/hooks/hooks.json. The standard hooks/hooks.json is loaded automatically, so manifest.hooks
should only reference additional hook files.
Steps to Reproduce
Test 1: Verify --plugin-dir auto-loads hooks (warning is correct here)
- Create a minimal test plugin WITHOUT hooks in manifest:
mkdir -p /tmp/test-plugin/.claude-plugin /tmp/test-plugin/hooks
cat > /tmp/test-plugin/.claude-plugin/plugin.json << 'EOF'
{
"name": "hooks-test-plugin",
"version": "1.0.0",
"description": "Test hooks auto-loading behavior"
}
EOF
cat > /tmp/test-plugin/hooks/hooks.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'HOOK FIRED' > /tmp/hook-test-output.txt"
}
]
}
]
}
}
EOF
- Run Claude with --plugin-dir:
claude --plugin-dir /tmp/test-plugin
- In the session, run any Bash command (e.g.,
ls)
- Check if hook fired:
cat /tmp/hook-test-output.txt
Result: File contains "HOOK FIRED" ✓ - Hooks DO auto-load for --plugin-dir
---
Test 2: Verify marketplace does NOT auto-load hooks (warning is WRONG here)
- Add marketplace.json to the same plugin:
cat > /tmp/test-plugin/.claude-plugin/marketplace.json << 'EOF'
{
"name": "hooks-test-marketplace",
"owner": {
"name": "Test Owner",
"email": "test@test.com"
},
"metadata": {
"description": "Test marketplace for hooks auto-loading",
"version": "1.0.0"
},
"plugins": [
{
"name": "hooks-test-plugin",
"source": "./"
}
]
}
EOF
- Initialize as git repo:
cd /tmp/test-plugin
git init
git add -A
git config user.email "test@test.com"
git config user.name "Test"
git commit -m "Initial commit - no hooks in manifest"
- Clean previous test and install via marketplace:
rm -f /tmp/hook-test-output.txt
claude /plugin marketplace add /tmp/test-plugin
- Restart Claude Code
- Run any Bash command (e.g.,
ls)
- Check if hook fired:
cat /tmp/hook-test-output.txt
Result: File does NOT exist ✗ - Hooks do NOT auto-load for marketplace installations
---
Summary: The behavior differs by installation method:
| Installation Method | Auto-loads hooks/hooks.json? | Needs manifest registration? | Warning shown? |
|---------------------|------------------------------|------------------------------|----------------|
| --plugin-dir | ✓ Yes | No | Yes (correct) |
| Marketplace | ✗ No | ✓ Yes | Yes (WRONG) |
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.76 (npm-global)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
VS Code integrated terminal
Additional Information
Impact: This creates a "ping-pong cycle" for plugin developers:
- See duplicate warning → remove hooks registration
- Hooks stop firing → re-add registration
- See warning again → repeat
Real-world example: We experienced this exact cycle multiple times (commits on Jan 5, 6, 8, 14) before implementing POC to prove the warning was context-dependent.
Current workaround: Ignore the warning and keep "hooks": "./hooks/hooks.json" in plugin.json for marketplace-distributed plugins. Document this as a known false positive.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗