[BUG] Hooks defined in managed/policy settings are not loaded into hook registry
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?
What's Wrong?
Hooks defined in managed policy settings (via managed-settings.json, Windows registry HKLM\SOFTWARE\Policies\ClaudeCode, or macOS managed preferences) are not included in hook registry lookups, even though other settings from the same source are correctly applied. For example, setting "allowManagedHooksOnly": true in managed settings correctly blocks user and project hooks and displays a message at startup, confirming the managed settings file is read. However, hooks defined in the same file under the "hooks" key never appear in /hooks and never fire. Debug logs show Found 0 hook matchers in settings at startup despite the hooks being present in the managed settings JSON. This appears to be the same underlying issue as #18900, #18547, #16288, and #12634 — the hook lookup system only queries the user/project/local settings registry, not hooks loaded from managed/policy settings sources.
What Should Happen?
Hooks defined in managed policy settings should be loaded into the same hook registry that is queried during hook lookups, or the lookup functions should check all hook sources including managed settings. When "hooks" and "allowManagedHooksOnly": true are both present in managed settings, the managed hooks should appear in /hooks and fire on their corresponding lifecycle events. This is critical for enterprise deployments where administrators need to enforce organization-wide hooks (such as security policy enforcement or audit logging) that users cannot override or remove.
Error Messages/Logs
No Error Message. Just hooks from managed settings not loaded.
Steps to Reproduce
- Create a managed settings file with hooks:
macOS — /Library/Application Support/ClaudeCode/managed-settings.json:
{
"allowManagedHooksOnly": true,
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "echo managed-hook-test >&2"
}
]
}
]
}
}
Windows — C:\Program Files\ClaudeCode\managed-settings.json (or via registry at HKLM\SOFTWARE\Policies\ClaudeCode with a Settings REG_SZ value containing the same JSON).
- Start Claude Code with claude --debug.
- Observe: The startup message indicates managed-only hooks are enforced, confirming the file was read. But /hooks shows no hooks, and debug logs show:
Getting matching hook commands for SessionStart with query: startup
Found 0 hook matchers in settings
Matched 0 unique hooks for query "startup" (0 before deduplication)
- Compare: Move the same "hooks" block to ~/.claude/settings.json (user settings), remove allowManagedHooksOnly, restart Claude Code. The hooks now appear in /hooks and fire correctly.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.74
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗