Skip to content

Remote curated plugins ignore per-plugin enabled=false config #28443

Description

@Michaelihc

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

Codex Doctor v0.140.0 · windows-x86_64

Environment
  ✓ system       en-US
  ✓ runtime      standalone (windows, package <CODEX_HOME>\packages\standalone\releases\0.140.0-x86_64-pc-windows-msvc, bin <CODEX_HOME>\packages\standalone\releases\0.140.0-x86_64-pc-windows-msvc\bin, resources <CODEX_HOME>\packages\standalone\releases\0.140.0-x86_64-pc-windows-msvc\codex-resources, path <CODEX_HOME>\packages\standalone\releases\0.140.0-x86_64-pc-windows-msvc\codex-path)
  ✓ install      consistent
  ✓ search       file exists (bundled)
  ✓ git          git version 2.54.0.windows.1
  ✓ terminal     Windows Terminal · zellij 0.44.3
  ✓ state        databases healthy
  ✓ threads      rollout files and state DB thread inventory agree

Configuration
  ✓ config       loaded
  ✓ auth         auth is configured
  ✓ mcp          1 server (1 stdio) · 0 disabled
  ✓ sandbox      restricted fs + restricted network · approval OnRequest

Updates
  ✓ updates      update configuration is locally consistent

Connectivity
  ✓ network      no proxy env vars
  ✓ websocket    connected (HTTP 101 Switching Protocols) · 15s timeout
  ✓ reachability active provider endpoints are reachable over HTTP

Background Server
  ○ app-server   not running (ephemeral mode)

17 ok · 1 idle · 0 warn · 0 fail ok

What issue are you seeing?

Per-plugin enabled = false entries in ~/.codex/config.toml do not suppress remote curated plugin injection in fresh Codex CLI sessions.

My config explicitly disables several remote curated plugins:

[plugins."data-analytics@openai-curated-remote"]
enabled = false

[plugins."figma@openai-curated-remote"]
enabled = false

[plugins."product-design@openai-curated-remote"]
enabled = false

[plugins."public-equity-investing@openai-curated-remote"]
enabled = false

Despite that, a fresh codex exec --ephemeral session still exposes those plugins in the model-visible plugin context:

browser
computer-use
data-analytics
documents
figma
github
pdf
presentations
product-design
public-equity-investing
spreadsheets

This is not stale context from an existing conversation. It reproduces in a new ephemeral CLI session after upgrading from 0.139.0 to 0.140.0.

codex plugin list does 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:

documents@openai-primary-runtime
pdf@openai-primary-runtime
spreadsheets@openai-primary-runtime
presentations@openai-primary-runtime

The remote curated plugin bundles are cached locally under a path like:

<CODEX_HOME>\plugins\cache\openai-curated-remote\

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?

  1. Use Codex CLI 0.140.0 on Windows with plugins enabled.

  2. Add explicit disabled entries for remote curated plugins to ~/.codex/config.toml:

    [plugins."data-analytics@openai-curated-remote"]
    enabled = false
    
    [plugins."figma@openai-curated-remote"]
    enabled = false
    
    [plugins."product-design@openai-curated-remote"]
    enabled = false
    
    [plugins."public-equity-investing@openai-curated-remote"]
    enabled = false
  3. Start a fresh ephemeral session:

    codex exec --ephemeral --skip-git-repo-check -C <empty-test-dir> "List the plugins directly visible/injected into this context. Do not run tools. Return only the plugin names, one per line."
  4. Observe that the disabled remote curated plugins are still injected:

    data-analytics
    figma
    product-design
    public-equity-investing
    
  5. As a control, disable all plugin/app surfaces plus the explicit node_repl MCP server:

    codex exec --ephemeral --skip-git-repo-check -C <empty-test-dir> `
      -c 'features.plugins=false' `
      -c 'features.apps=false' `
      -c 'mcp_servers.node_repl.enabled=false' `
      "List the plugins directly visible/injected into this context. Do not run tools. Return only the plugin names, one per line. If none are visible, return NONE."
  6. Control output:

    NONE
    

What is the expected behavior?

If a plugin has this config:

[plugins."plugin-name@marketplace"]
enabled = false

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 in codex 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-remote plugin injection. The only reliable workaround found is feature-level disabling:

[features]
plugins = false
apps = false

[mcp_servers.node_repl]
enabled = false

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:

This report is narrower: it reproduces on codex-cli 0.140.0 with explicit per-plugin enabled = false entries for openai-curated-remote plugins, in fresh codex exec --ephemeral sessions.

Activity

added
bugSomething isn't working
CLIIssues related to the Codex CLI
windows-osIssues related to Codex on Windows systems
skillsIssues related to skills
configIssues involving config.toml, config keys, config merging, or config updates
execIssues related to the `codex exec` subcommand
on Jun 16, 2026

MakenRosa commented on Jun 17, 2026

@MakenRosa

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 calls load_plugins_from_layer_stack(..., self.remote_installed_plugin_configs(), ..., config.remote_plugin_enabled).
  • remote_installed_plugin_configs() converts the remote-installed cache into PluginConfig { enabled: plugin.enabled, ... } for every locally cached remote bundle.
  • merge_configured_plugins_with_remote_installed() then merges those extra_plugins into 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 remote linear@openai-curated-remote style 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 says enabled = 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

@Terryniu

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:

  1. A plugin configured with enabled=false should not contribute skills to the effective model-visible skill catalog.
  2. Its SKILL.md files should not be injected into or actively read by fresh tasks.
  3. A disabled plugin should not consume developer-context, skill metadata, or token budget.
  4. 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:

Suggested fixes:

  1. Apply per-plugin enabled=false before constructing the effective skill catalog.
  2. Exclude disabled plugin skills from all model-visible skill metadata.
  3. Prevent disabled plugin SKILL.md files from being selected or read by fresh turns.
  4. Rebuild or invalidate the effective catalog after plugin configuration or cache changes.
  5. Expose the effective logical plugin ID, physical source, manifest version, enabled state, and selected skill paths in diagnostics.
  6. 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

@f1ashades

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 = false

After 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 with enabled = false work; 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

@helgobert8-sketch

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:

  1. Opened the Codex CLI plugin browser with /plugins.

  2. Pressed Space on the installed Superpowers entry. The UI changed to Disabled / Space to enable.

  3. Confirmed that Codex persisted:

    [plugins."superpowers@openai-curated-remote"]
    enabled = false
  4. Fully terminated all ChatGPT, codex, and codex-code-mode-host processes, restarted Desktop, and ran a brand-new codex exec --json --ephemeral task in a clean disposable Git fixture.

Actual result:

  • The fresh task still announced that it was using Superpowers.
  • It explicitly read Superpowers SKILL.md files from the remote curated cache, including using-superpowers, test-driven-development, and verification-before-completion, plus bundled references.
  • A separate codex debug prompt-input inspection reported zero Superpowers matches while the real codex exec run 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.

davideluque commented on Sep 16, 2026

@davideluque

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.

s2software commented on Sep 17, 2026

@s2software

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingconfigIssues involving config.toml, config keys, config merging, or config updatesexecIssues related to the `codex exec` subcommandskillsIssues related to skillswindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions