[BUG] Plugin hooks registered but not firing in VSCode extension

Status Closed — not planned
Reported on v2.1.9
Maintainer reply None cached
Activity 12 comments · opened Jan 16, 2026 · closed May 24, 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?

GitHub Bug Report: VS Code Plugin Hooks Not Loading

Repository: https://github.com/anthropics/claude-code/issues/new

Title: VS Code Extension: Plugin hooks.json not loaded - hooks only work from settings.json

---

Summary

Hooks defined in a plugin's hooks/hooks.json file are not loaded by the VS Code extension. Hooks only fire when defined directly in .claude/settings.json or ~/.claude/settings.json.

Environment

  • Platform: macOS (Darwin 25.2.0)
  • Claude Code: VS Code Extension
  • Date: 2025-01-16

Expected Behavior

According to hooks documentation, plugins can provide hooks via hooks/hooks.json:

Plugins can provide hooks via hooks/hooks.json

The hookify plugin demonstrates this pattern with its hooks/hooks.json file.

When a plugin is enabled via enabledPlugins in settings.json, its hooks should automatically be registered and fire on the appropriate events.

Actual Behavior

Hooks defined in a plugin's hooks/hooks.json are not loaded by the VS Code extension. The hooks only fire when copied directly into .claude/settings.json.

Impact

  • Plugin portability: Plugins cannot be self-contained with their own hooks
  • Plugin marketplace: Published plugins with hooks may not work in VS Code
  • User experience: Users must manually copy hooks from plugin to settings.json
  • Maintenance burden: Hook updates in plugins don't propagate - users must re-copy each time plugin is updated

Additional:

  1. CLI loads the plugin hook correctly, without copying to settings.json

Related

False positives for duplicate issue:

Have reviewed and the ones below that relate are closed as duplicates or done, but the duplicates were false positives and this issue persist.

https://github.com/anthropics/claude-code/issues/10997
https://github.com/anthropics/claude-code/issues/11509
https://github.com/anthropics/claude-code/issues/11544
https://github.com/anthropics/claude-code/issues/6305

What Should Happen?

Claude VSCode extension should recognize local file plugin hooks in place without need to copy into settings.json

Error Messages/Logs

Steps to Reproduce

Reproduction Steps

1. Create a plugin with hooks

Create directory structure:

.claude/plugins/my-plugin/
├── .claude-plugin/
│   └── marketplace.json.json
│   └── plugin.json
└── hooks/
    ├── __init__.py
    └── hooks.json

marketplace.json

{
  "name": "my-plugin-marketplace",
  "version": "1.0.0",
  "description": "Test local marketplace",
  "owner": {
    "name": "Local",
    "email": "local@localhost"
  },
  "plugins": [
    {
      "name": "my-plugin",
      "version": "1.0.0",
      "description": "Test plugin with hooks"
      "source": "./"
    }
  ]
}

plugin.json:

{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Test plugin with hooks"
}

hooks/hooks.json:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"UserPromptSubmit\", \"additionalContext\": \"Hook fired from plugin!\"}}'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

2. Enable the plugin in settings.json

.claude/settings.json:

{
  "extraKnownMarketplaces": {
    "my-plugin-marketplace": {
      "source": {
        "source": "directory",
        "path": "./.claude/plugins/my-plugin"
      }
    }
  },
  "enabledPlugins": {
    "my-plugin@my-plugin-marketplace": true
  }
}

3. Test in VS Code

  1. Open project in VS Code
  2. Open Claude Code extension
  3. Send any message

Result: No hook output appears. The UserPromptSubmit hook does not fire.

4. Workaround - Add hooks directly to settings.json

.claude/settings.json:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"UserPromptSubmit\", \"additionalContext\": \"Hook fired from settings.json!\"}}'",
            "timeout": 10
          }
        ]
      }
    ]
  },
  "extraKnownMarketplaces": { ... },
  "enabledPlugins": { ... }
}

Result: Hook ONLY fires correctly when defined in settings.json. Does not fire when in setup as above.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

VSCode Extension v.2.1.9

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

11 Comments

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/16288
  2. https://github.com/anthropics/claude-code/issues/12649
  3. https://github.com/anthropics/claude-code/issues/16114

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

EarthmanWeb · 7 months ago

https://github.com/anthropics/claude-code/issues/16288
Does not relate - 16288 is specific to CLI only

https://github.com/anthropics/claude-code/issues/12649
Relates, but was false-positive closed as a duplicate, when it actually was not

https://github.com/anthropics/claude-code/issues/16114
Also relates, but was falsely closed due to no one taking action on it

Please pay attention to this very real bug. If required I can post a demo video repro.

backnotprop · 7 months ago

I have users experiencing the same issue

https://github.com/backnotprop/plannotator/issues/99

lukaferlez · 7 months ago
I have users experiencing the same issue backnotprop/plannotator#99

We have tried doing the workaround and copying the hooks configuration directly into settings.json and it still does not work.

This is on Windows btw, so it's not a macos issue only.

drorweka · 6 months ago

seeing this issue on Linux/KDE (peon ping works from claude code console but not from vscode)

nekon1987 · 6 months ago

same here on windows

butterflysky · 5 months ago

reproducing on my system too, Linux, v2.1.72, PreToolUse from ~/.claude/settings.json, log showing "0 hook matchers"

relevant config from my settings.json:

"hooks": {
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "/home/butterfly/.cargo/bin/cc-toolgate",
          "timeout": 5
        }
      ]
    }
  ],
  "PreCompact": [],
  "SessionStart": []
}
TedRubber · 5 months ago

Same issue I posted in #28964 and found in #18547. Issue started with 2.1.47 Git Bash change.

bibi-meow · 4 months ago

Still reproducing on Windows 11 / VSCode extension v2.1.92 (2026-04-13). Same symptom as OP.

Confirmed via plugin bibi-meow/dynamic-prompt-harness

  • /reload-plugins reports 5 hooks loaded, no errors.
  • /doctor shows 0 plugin errors.
  • Plugin hooks/hooks.json declares PreToolUse / PostToolUse / UserPromptSubmit / PreCompact with "command": "python -m dynamic_prompt_harness <event>".
  • Developer Window reload applied.

Control tests (same machine, same plugin cache)

| Path | Hook fires? |
|---|---|
| Manual python -m dynamic_prompt_harness pre_tool_use with a CC-shaped payload on stdin | ✅ |
| claude -p "run: ls -la" --allowed-tools Bash from a git bash terminal | ✅ (probe log written on PreToolUse) |
| Tool call from inside VSCode native extension | ❌ (no probe log, no dph.log, no stderr) |

So the plugin itself works; the VSCode extension is not dispatching plugin-scope hooks to the tool-invocation path.

Legacy hooks defined directly in project .claude/settings.json do fire in the same VSCode session (confirmed via another project's protect-diary.sh), so the hook subsystem as a whole is healthy — only plugin-scope hook wiring is missing.

Workaround confirmed: copying the plugin's hook commands into ~/.claude/settings.json makes them fire in VSCode. But as OP notes, this defeats plugin portability.

Happy to provide a minimal repro repo if useful — the plugin above already serves as one. Please consider un-staling.

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

pleasedodisturb · 2 months ago

oh come on

Showing cached comments. Read the full discussion on GitHub ↗