[BUG] Misleading "duplicate hooks" warning for marketplace-installed plugins

Resolved 💬 3 comments Opened Jan 15, 2026 by Jonathan-A-White Closed Jan 18, 2026

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)

  1. 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
  1. Run Claude with --plugin-dir:
claude --plugin-dir /tmp/test-plugin
  1. In the session, run any Bash command (e.g., ls)
  1. 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)

  1. 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
  1. 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"
  1. Clean previous test and install via marketplace:
rm -f /tmp/hook-test-output.txt
claude /plugin marketplace add /tmp/test-plugin
  1. Restart Claude Code
  1. Run any Bash command (e.g., ls)
  1. 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:

  1. See duplicate warning → remove hooks registration
  2. Hooks stop firing → re-add registration
  3. 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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗