[BUG] Plugin hooks registered but not firing in VSCode extension
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:
- CLI loads the plugin hook correctly, without copying to settings.json
Related
- hookify plugin - Official plugin with hooks.json
- Hooks documentation
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
- Open project in VS Code
- Open Claude Code extension
- 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_
Showing cached comments. Read the full discussion on GitHub ↗
11 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
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.
I have users experiencing the same issue
https://github.com/backnotprop/plannotator/issues/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.
seeing this issue on Linux/KDE (peon ping works from claude code console but not from vscode)
same here on windows
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:
Same issue I posted in #28964 and found in #18547. Issue started with 2.1.47 Git Bash change.
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-pluginsreports 5 hooks loaded, no errors./doctorshows 0 plugin errors.hooks/hooks.jsondeclaresPreToolUse/PostToolUse/UserPromptSubmit/PreCompactwith"command": "python -m dynamic_prompt_harness <event>".Control tests (same machine, same plugin cache)
| Path | Hook fires? |
|---|---|
| Manual
python -m dynamic_prompt_harness pre_tool_usewith a CC-shaped payload on stdin | ✅ ||
claude -p "run: ls -la" --allowed-tools Bashfrom a git bash terminal | ✅ (probe log written onPreToolUse) || 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.jsondo fire in the same VSCode session (confirmed via another project'sprotect-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.jsonmakes 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.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
oh come on