Repository navigation
Remote curated plugins ignore per-plugin enabled=false config #28443
Description
Activity
I traced this through the plugin loader and the report looks reproducible from the current code path.
What happens today:
plugins_for_config_with_force_reload()builds the load cache key from only persisted user plugin config + skill rules +remote_plugin_enabled, then callsload_plugins_from_layer_stack(..., self.remote_installed_plugin_configs(), ..., config.remote_plugin_enabled).remote_installed_plugin_configs()converts the remote-installed cache intoPluginConfig { enabled: plugin.enabled, ... }for every locally cached remote bundle.merge_configured_plugins_with_remote_installed()then merges thoseextra_pluginsinto user config.- For local curated vs remote curated name conflicts,
prefer_remote_curated_conflicts == config.remote_plugin_enabled, so when remote plugins are enabled, the remotelinear@openai-curated-remotestyle entry intentionally replaces local curated entries with the same plugin name. - There is no special case for a user-authored
[plugins."foo@openai-curated-remote"] enabled = false; if the remote installed cache saysenabled = true, the remote cache entry is inserted/overwritten during the extra-plugin merge.
Existing test coverage already demonstrates the conflict behavior:
cargo test -p codex-core-plugins remote_installed_cache_prefers_remote_curated_conflicts_when_remote_plugin_enabled --lib
This passes and asserts that with remote_plugin = true, a local linear@openai-curated entry is replaced by linear@openai-curated-remote.
I think the missing behavior is precedence for explicit user disablement. A narrow fix would be for merge_configured_plugins_with_remote_installed() to preserve an explicit configured entry for the same remote plugin key when that entry is enabled = false, or to overlay user config after remote-installed config specifically for enabled. The important part is that the remote-installed server state should be allowed to add installed plugins, but not silently re-enable a plugin the local config explicitly disabled.
This also explains the confusing codex plugin list angle: listing and execution appear to consult different surfaces. Execution sees self.remote_installed_plugin_configs() during plugins_for_config(), while the list UI can omit those remote installed plugins depending on visible marketplaces/configured state. So the plugin can be injected during exec even when it is not obvious from plugin list.
Terryniu commented on Jul 25, 2026
Windows Desktop reproduction: disabled remote curated Superpowers remains in the effective skill catalog and is actively read
I am seeing the same underlying behavior in Codex Windows Desktop: Superpowers remains present in the effective skill catalog, and its SKILL.md files can still be actively read even though the plugin is explicitly disabled.
Codex feedback ID:
019f8781-8ecd-73c1-8aea-2c0890616124
Environment:
- Windows 11 x64
- Codex Desktop App: 26.721.4979.0
- Codex Core: 0.146.0-alpha.3.1
- Model: gpt-5.6-sol
- Currently active Superpowers manifest version: 6.2.0
Configuration:
[plugins."superpowers@openai-curated"]
enabled = false
The user-facing plugin identifier is superpowers@openai-curated, while the currently active runtime cache source is under openai-curated-remote.
This appears to be Codex's normal logical-plugin-ID to remote-cache-backend mapping, not two independently active Superpowers plugins. Other curated plugins on the same installation use the same mapping pattern.
Expected behavior:
- A plugin configured with enabled=false should not contribute skills to the effective model-visible skill catalog.
- Its SKILL.md files should not be injected into or actively read by fresh tasks.
- A disabled plugin should not consume developer-context, skill metadata, or token budget.
- Fresh tasks and App/Core restarts should construct the effective catalog from the current plugin configuration.
Actual behavior:
- Fresh tasks still receive all 14 distinct Superpowers skills in the effective developer skill catalog.
- Full initial catalog snapshots contain 15 Superpowers path/reference occurrences.
- The 15 occurrences are raw catalog/path-reference matches across 14 distinct skills; they do not represent 15 distinct Superpowers skills.
- Across 24 complete catalog snapshots, 360 Superpowers catalog/path references were observed.
- Superpowers SKILL.md files were also explicitly read during real task execution.
The catalog/path-reference counts above are not being presented as actual file-read counts.
Using a stricter metric that counts only tool calls whose arguments explicitly contain a Superpowers SKILL.md path, with duplicate paths inside one call counted once:
- openai-curated-remote version 6.1.1 was explicitly read 63 times across 11 tasks before that active cache version was replaced;
- the currently active openai-curated-remote version 6.2.0 has already been explicitly read 3 times in one task;
- those 6.2.0 reads were verification-before-completion twice and finishing-a-development-branch once;
- total strict explicit SKILL.md reads: 66;
- the older openai-curated version 5.1.3 and version 5.1.1 had zero strict reads.
An earlier broader detector found 152 path/load signals, but that was a wider heuristic and should not be treated as equivalent to explicit SKILL.md reads. The strict explicit-path result is 66.
Active-version verification:
The currently injected version is genuinely Superpowers 6.2.0, not merely a directory label.
Its active plugin manifest reports:
- name: superpowers
- version: 6.2.0
- hooks: {}
The active 6.2.0 plugin tree contains no registered SessionStart hook and no active .codex-plugin/hooks directory.
A fresh task created under the current App/Core process selected only the 6.2.0 Superpowers skill source. Older 5.1.3 and 6.1.1 paths were absent from that task's effective catalog.
Older manifest versions and backup or temporary copies exist on disk, but they are not simultaneously active injection sources for current fresh tasks.
This rules out the following explanations for the current behavior:
- the active Superpowers version being outdated;
- a stale 5.1.3 or 6.1.1 source being selected in the current fresh task;
- multiple Superpowers versions being injected simultaneously;
- a registered Superpowers SessionStart hook causing the injection;
- the configured plugin identifier referring to an unrelated second plugin.
Cache and catalog refresh evidence:
In a previous controlled check, the active Superpowers cache directory was moved out of its discovery path after a complete backup was created.
A fresh task in the same App/Core process still received:
- the same developer-context size;
- the same effective skill catalog size;
- the same Superpowers references.
The plugin manager did not restore the directory during that check.
This indicates that the running Desktop process retained a previously constructed skill discovery or catalog snapshot rather than rebuilding it from the current disk and configuration state.
The cache was restored afterward, and the restored files matched the pre-test hash manifest. No permanent plugin or configuration changes were left behind.
Impact:
This evidence does not prove that Superpowers is responsible for all Codex latency, token use, or tool failures. Task complexity remains a major confounding variable.
It does demonstrate that:
- per-plugin enabled=false semantics are not being respected;
- disabled skills remain in model-visible catalog metadata;
- disabled SKILL.md files can still be actively read during task execution;
- disabled plugin instructions can influence workflow behavior;
- users cannot reliably control which curated plugin skills enter task context;
- plugin configuration and on-disk cache state are not consistently reflected in the effective Desktop skill catalog.
The currently active Superpowers version already includes the newer Codex-related manifest behavior, including hooks: {} and no registered SessionStart hook.
Reinstalling or updating the same Superpowers 6.2.0 version therefore does not appear to address this issue. The remaining failure boundary appears to be Codex Desktop/Core per-plugin disable handling, skill discovery, catalog construction, or catalog invalidation.
Related issues:
- Failed to parse the request body as JSON: client_metadata.x-codex-installation-id: EOF while parsing a string #21520: disabled skills or plugins still injected into request bodies in Windows Desktop
- Codex Windows Desktop: Agent uses stale plugin cache path after plugin update, and session execution details are lost after restart #24390: stale plugin cache or path refresh behavior in Windows Desktop
- Windows Codex Desktop persists volatile plugin cache hash paths in sessions, causing older threads to lose skills after plugin cache updates #25285: volatile plugin cache paths persisted in Windows Desktop sessions
Suggested fixes:
- Apply per-plugin enabled=false before constructing the effective skill catalog.
- Exclude disabled plugin skills from all model-visible skill metadata.
- Prevent disabled plugin SKILL.md files from being selected or read by fresh turns.
- Rebuild or invalidate the effective catalog after plugin configuration or cache changes.
- Expose the effective logical plugin ID, physical source, manifest version, enabled state, and selected skill paths in diagnostics.
- Add a Desktop regression test covering a logical openai-curated plugin ID backed by an openai-curated-remote cache source.
I can provide additional sanitized timestamps, manifest hashes, or aggregate metrics if needed, using the Codex feedback ID above.
f1ashades commented on Aug 7, 2026
Additional reproduction from Codex Desktop on macOS:
- Codex Desktop:
26.803.41515 - app-server user agent:
Codex Desktop/0.147.0-alpha.6.5 - Platform: macOS arm64
- Remote curated plugin: Superpowers
6.2.0
Disabling Superpowers in the Desktop Plugins UI wrote:
[plugins."superpowers@openai-curated-remote"]
enabled = falseAfter fully quitting with Cmd-Q, reopening Desktop, and creating a brand-new task, all 14 superpowers:* skills were still exposed and using-superpowers was selected automatically. This rules out retained context from an existing task.
I also reproduced this with an independent fresh app-server process: skills/list reported 14/14 Superpowers skills enabled despite the plugin-level setting. Trying either superpowers@openai-curated-remote or superpowers@openai-curated as the disabled plugin identity did not change the result.
Verified controls/workarounds:
- Individual
[[skills.config]]overrides withenabled = falsework; disabling all 14 skills removes them from the model-visible skill list. - Uninstalling Superpowers removes its remote cache and the skills disappear from new Desktop tasks.
This suggests the remote plugin state is being merged after, or without honoring, the local plugin-level enabled=false override.
helgobert8-sketch commented on Aug 20, 2026
Independent Windows reproduction on Desktop 26.814.5517.0 / CLI 0.145.0-alpha.4
I reproduced the same failure with a remote curated plugin and a controlled uninstall comparison.
Environment:
- Windows 11 x64
- Codex Desktop:
26.814.5517.0 - Codex CLI:
0.145.0-alpha.4 - Remote curated plugin: Superpowers
6.3.0
Reproduction:
-
Opened the Codex CLI plugin browser with
/plugins. -
Pressed
Spaceon the installed Superpowers entry. The UI changed toDisabled/Space to enable. -
Confirmed that Codex persisted:
[plugins."superpowers@openai-curated-remote"] enabled = false
-
Fully terminated all
ChatGPT,codex, andcodex-code-mode-hostprocesses, restarted Desktop, and ran a brand-newcodex exec --json --ephemeraltask in a clean disposable Git fixture.
Actual result:
- The fresh task still announced that it was using Superpowers.
- It explicitly read Superpowers
SKILL.mdfiles from the remote curated cache, includingusing-superpowers,test-driven-development, andverification-before-completion, plus bundled references. - A separate
codex debug prompt-inputinspection reported zero Superpowers matches while the realcodex execrun still received and used the skills. This suggests the debug rendering and effective execution context can disagree for remote plugin injection.
Control:
- Uninstalled only Superpowers through the supported plugin-management path.
- Fully terminated and restarted Codex again.
- Confirmed the Superpowers cache did not return and the other eight remote plugin cache entries remained present.
- Re-ran the same fixture prompt with the same SHA-256 and identical initial Git tree.
- The post-uninstall run contained no Superpowers skill path or skill announcement, completed the implementation in the same turn, and passed all 3 tests.
Observed single-pair impact (not presented as a general cost estimate): input tokens dropped from 294,247 to 62,035, and completed tool steps from 6 to 2 after uninstall. The important correctness result is that the documented per-plugin toggle did not establish the disabled treatment, while uninstall did.
This confirms the bug persists on a newer Windows Desktop build and Superpowers version. I can provide sanitized JSONL excerpts or exact command lines if maintainers need them.
I have the same problem here. I can’t disable a remotely curated plugin; I can only uninstall it.
If I disable it in my local CLI, it gets enabled again because it’s still enabled remotely, so the remote setting overrides my local configuration.
I’m experiencing the same issue. Disabling plugins only works reliably when done through the Codex VS Code extension settings (Plugins > Plugins).
However, this introduces another problem: the disabled plugins also disappear from the ChatGPT tool selector, even though they remain available to the LLM and can still be used by the model. They are simply no longer selectable manually in ChatGPT.
Ideally, disabling plugins in Codex should not affect their availability in ChatGPT.
What version of Codex CLI is running?
codex-cli 0.140.0
What subscription do you have?
Not specified.
Which model were you using?
gpt-5.5
What platform is your computer?
Windows x64
What terminal emulator and version are you using (if applicable)?
Windows Terminal, running PowerShell.
Codex doctor report
What issue are you seeing?
Per-plugin
enabled = falseentries in~/.codex/config.tomldo not suppress remote curated plugin injection in fresh Codex CLI sessions.My config explicitly disables several remote curated plugins:
Despite that, a fresh
codex exec --ephemeralsession still exposes those plugins in the model-visible plugin context:This is not stale context from an existing conversation. It reproduces in a new ephemeral CLI session after upgrading from
0.139.0to0.140.0.codex plugin listdoes not show these remote curated plugins as locally installed/enabled through the regular CLI marketplace path. It only shows the primary runtime plugins as installed/enabled in this environment:The remote curated plugin bundles are cached locally under a path like:
but the user-facing installed plugin list and the per-plugin disabled config do not reflect or control the injected session context.
What steps can reproduce the bug?
Use Codex CLI
0.140.0on Windows with plugins enabled.Add explicit disabled entries for remote curated plugins to
~/.codex/config.toml:Start a fresh ephemeral session:
Observe that the disabled remote curated plugins are still injected:
As a control, disable all plugin/app surfaces plus the explicit
node_replMCP server:Control output:
What is the expected behavior?
If a plugin has this config:
then a fresh Codex session should not inject that plugin's skills/plugin instructions into the model-visible context.
If remote curated plugins are account-synced or controlled by a different identifier than
plugin-name@openai-curated-remote, Codex should expose that state clearly incodex plugin list,codex doctor, and documentation, and provide a documented per-host/per-session way to disable each remote curated plugin without turning off all plugins.Actual behavior
Per-plugin disabled entries appear to be ignored for
openai-curated-remoteplugin injection. The only reliable workaround found is feature-level disabling:That removes the unwanted remote curated plugin context, but it also disables all plugin/app functionality and is too broad for users who want primary runtime plugins or selected plugins enabled.
Additional information
Related/adjacent issues found before filing:
enabled = falsewere still injected into the request body.This report is narrower: it reproduces on
codex-cli 0.140.0with explicit per-pluginenabled = falseentries foropenai-curated-remoteplugins, in freshcodex exec --ephemeralsessions.