[bug] managed-settings.json `enabledPlugins` is not enforced — users can uninstall org-managed plugins; combined with #45323, plugin distribution is broken end-to-end

Resolved 💬 2 comments Opened May 13, 2026 by dvirmoyal25 Closed May 13, 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?

The managed-settings.json file documents enabledPlugins + extraKnownMarketplaces as the mechanism for org-wide plugin distribution. In practice, two compounding bugs make managed-settings.json non-functional for security-critical plugins:

  1. #45323 — CLI does not auto-install plugins declared in managed-settings.json enabledPlugins. Users must manually run /plugin marketplace add and /plugin install.
  2. This issue — Even after manual install, users can /plugin uninstall a plugin declared in managed-settings.json. Claude Code accepts the uninstall, hooks stop running, and the UI shows broken state (Status: Enabled with no working cache). There is no reconciliation, no auto-reinstall, no warning.

Together, enabledPlugins in managed-settings.json is a hint, not a policy. There is no point in the lifecycle (initial install, ongoing enforcement, recovery from user action) where the managed-settings.json declaration is actually honored.

For organizations deploying security plugins via managed-settings.json (credential guards, audit hooks, sensitive-file blockers), there is currently no path to enforce these protections through Claude Code's own configuration surface:

  • Bug #45323 means users must opt in manually — managed-settings.json provides no default-on protection
  • This bug means users can opt out unilaterally — managed-settings.json cannot prevent removal
  • Combined, enabledPlugins in managed-settings.json cannot be relied on for any security-critical use case

<img width="1703" height="924" alt="Image" src="https://github.com/user-attachments/assets/8a8bc56d-bd42-4b97-9c3b-9e0230c10edb" />

What Should Happen?

enabledPlugins in managed-settings.json should be enforced throughout the plugin lifecycle:

  • On startup: if a plugin declared in managed-settings.json is not installed, install it automatically (fixes #45323)
  • On uninstall: block /plugin uninstall for plugins declared in managed-settings.json with a clear message ("this plugin is managed by your organization — contact your administrator")
  • On state drift: if cache is missing for a plugin declared in managed-settings.json, reinstall it on next startup rather than show "Status: Enabled" with broken cache

Precedent: disableBypassPermissionsMode: "disable" in managed-settings.json is already enforced and cannot be overridden by the user. The same pattern should apply to plugin installation state declared in the same file.

Error Messages/Logs

1 error:
  Plugin "<plugin-name>" not cached at (not recorded)
  → Run /plugins to refresh the plugin cache

Failed to uninstall: Plugin "<plugin-name>@<marketplace-name>" is not installed in user scope. Use --scope to specify the correct scope.

Steps to Reproduce

  1. Configure managed-settings.json:
   {
     "enabledPlugins": {
       "security-plugin@org-marketplace": true
     },
     "extraKnownMarketplaces": {
       "org-marketplace": {
         "source": {
           "source": "github",
           "repo": "your-org/your-marketplace-repo",
           "ref": "main"
         }
       }
     }
   }
  1. Open Claude Code CLI on a fresh machine — plugin is not installed despite managed-settings.json declaration (per #45323).
  1. Manually run to work around #45323:
   /plugin marketplace add your-org/your-marketplace-repo
   /plugin install security-plugin@org-marketplace
  1. Verify hooks run on session start (expected, working).
  1. Run /plugin uninstall security-plugin@org-marketplacesucceeds without warning, despite managed-settings.json declaring this plugin as enabled.
  1. Open /plugins:
  • UI shows Status: Enabled and lists installed components (Hooks: SessionStart, PreToolUse)
  • But cache is gone — hooks no longer execute
  • Error: Plugin "<name>" not cached at (not recorded)
  • Attempting uninstall again fails with misleading "not installed in user scope" error
  1. Restart Claude Code — plugin does not auto-reinstall despite still being declared in managed-settings.json.

Claude Model

Other

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No — managed-settings.json enabledPlugins enforcement has never worked as documented.

Claude Code Version

2.1.140

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Related issues

  • #45323 — CLI doesn't auto-install plugins from managed-settings.json. This issue is the second half of the same broken story; closing #45323 alone would not fix uninstall-then-restart, and closing this alone would not fix initial install from managed-settings.json.
  • #23737, #28310 — feature requests for required/auto-install plugins, closed as duplicates of #19275 (race condition bug) without the feature ever shipping.

Workarounds (and why they're not sufficient)

  • MDM-managed wrapper scripts around the claude binary — works but defeats the purpose of managed-settings.json as a configuration surface
  • CLAUDE_CODE_PLUGIN_SEED_DIR baked into Docker images — works for CI/devcontainers but not for engineer laptops, and doesn't survive uninstall

Screenshot

[attach screenshot of /plugins showing Status: Enabled with "not cached" error and failed uninstall, with org-specific names cropped/redacted]

Configuration files

managed-settings.json excerpt above. Marketplace marketplace.json follows standard schema (git-subdir or relative-path source, both reproduce the bug).

View original on GitHub ↗

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