$skill invocation resolves stale cached plugin skill from not-installed marketplace plugin

Open 💬 4 comments Opened Jul 3, 2026 by federico-vitale

What issue are you seeing?

After hitting the outdated Superpowers issue described in issues #28846 / #29517, I installed the upstream Superpowers marketplace as superpowers-dev to use the newer version.

After that, Codex had:

  • superpowers@superpowers-dev installed and enabled, version 6.1.1
  • superpowers@openai-curated not installed
  • a stale/openai-curated Superpowers copy still present in the local plugin cache, version 5.1.4

The surprising behavior was that explicit $superpowers invocation resolved to the stale cached openai-curated copy, while plain natural-language invocation of superpowers resolved to the correct enabled superpowers-dev plugin.

Observed:

  • Prompt: invoca superpowers e dimmi la cartella da cui fai la discovery e la versione di superpowers. Non modificare alcun file
  • resolved to: ~/.codex/plugins/cache/superpowers-dev/superpowers/6.1.1/skills
  • version: 6.1.1
  • Prompt: invoca $superpowers e dimmi la cartella da cui fai la discovery e la versione di superpowers. Non modificare alcun file
  • resolved to the stale openai-curated cache path
  • version: 5.1.4

After adding an explicit config entry disabling the not-installed curated plugin, $superpowers started resolving correctly to superpowers-dev 6.1.1.

This suggests that $skill resolution may still consider cached skills from a not-installed plugin when another plugin with the same skill name is installed/enabled.

What steps can reproduce the bug?

  1. Have the old curated Superpowers plugin cache present locally, for example under:

~/.codex/plugins/cache/openai-curated-remote/superpowers/5.1.4/skills

  1. Do not have the curated plugin installed/enabled. In my case, codex plugin list showed the curated Superpowers plugin as not installed.
  1. Install and enable the upstream Superpowers marketplace as superpowers-dev.
  1. Confirm config contains the enabled upstream plugin:

superpowers@superpowers-dev enabled = true

  1. Start a new Codex session.
  1. Use a natural-language invocation:

invoca superpowers e dimmi la cartella da cui fai la discovery e la versione di superpowers. Non modificare alcun file

Observed result:
Codex resolves Superpowers from:
~/.codex/plugins/cache/superpowers-dev/superpowers/6.1.1/skills

  1. Start another fresh Codex session, or use the same environment.
  1. Use explicit $skill invocation:

invoca $superpowers e dimmi la cartella da cui fai la discovery e la versione di superpowers. Non modificare alcun file

Observed result before workaround:
Codex resolves Superpowers from the stale openai-curated cache:
~/.codex/plugins/cache/openai-curated-remote/superpowers/5.1.4/skills

  1. Add this explicit disable entry to ~/.codex/config.toml:

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

  1. Restart Codex and repeat the $superpowers prompt.

Observed result after workaround:
$superpowers resolves correctly to:
~/.codex/plugins/cache/superpowers-dev/superpowers/6.1.1/skills

What is the expected behavior?

Explicit $skill invocation should only resolve skills from installed/enabled plugins, or should disambiguate duplicate skill names using the enabled plugin state.

A cached plugin that is not installed should not participate in $skill resolution.

In this case, $superpowers should have resolved to superpowers@superpowers-dev 6.1.1, the only installed/enabled Superpowers plugin, instead of resolving to the stale cached superpowers@openai-curated 5.1.4 copy.

Additional information

This appears related to, but distinct from, #28846 and #29517.

Those issues report that superpowers@openai-curated is outdated compared with upstream. This issue is about what happens after installing an updated upstream marketplace to work around that: the stale curated copy can still be selected by explicit $skill invocation unless it is explicitly disabled in config, even though it is not installed.

Workaround that fixed the issue locally:

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

After adding that entry and restarting Codex, $superpowers resolved to:

~/.codex/plugins/cache/superpowers-dev/superpowers/6.1.1/skills

Environment:

  • macOS
  • Codex CLI observed: 0.142.5
  • Model: gpt-5.5
  • Affected both Codex App and CLI-style sessions
  • Upstream Superpowers marketplace source: https://github.com/obra/superpowers.git

View original on GitHub ↗

4 Comments

Don-Yin · 1 month ago

I saw a similar stale-skill-resolution failure in a local Codex session using a project/custom skill workflow. Keeping details generic here to avoid exposing local paths or project information.

Setup:

  • A canonical project skill had been updated recently.
  • A project-local skill path resolved correctly to that canonical updated skill.
  • A separate staging/mirror copy of the same skill name still existed on disk with older content.

Observed behavior:

  • The user explicitly invoked the skill by name with $skill syntax.
  • Most agents used the updated canonical skill.
  • At least one spawned subagent cited and used the stale staging/mirror copy instead.
  • The workflow then behaved inconsistently because not all agents were operating from the same effective skill source/version.
  • This was only visible after inspecting the session history and the file paths cited by subagents in their final reports.

Impact:

  • Skill-driven workflows become unreliable when parent and child agents can resolve different versions of the same skill.
  • Reviewer/subagent workflows are especially affected because the parent may believe a hard gate was applied while one child used stale instructions.
  • The failure mode is subtle: the task may still complete, but with degraded or inconsistent behavior rather than an obvious missing-skill error.

Expected behavior:

  • $skill invocation should resolve only to the currently active/canonical enabled skill source.
  • Subagents spawned from the same task should inherit or deterministically resolve the same skill identity/version as the parent.
  • If duplicate or stale skill copies are visible, Codex should either warn or prefer the active configured/project-local source deterministically.

This seems related to the stale cached-skill selection described in this issue, even though my case involved a project/custom skill mirror rather than only a marketplace plugin cache.

Jason-purse · 1 month ago

I can reproduce a closely related case on macOS with Codex App / CLI 0.142.5, but it shows up in the Codex App composer UI rather than only explicit $skill invocation.

Setup:

  • Installed/enabled Superpowers plugin:

superpowers@superpowers-marketplace, version 5.1.0

  • codex plugin list --json shows only that Superpowers plugin as installed/enabled.
  • codex plugin list --available --json also only reports that installed Superpowers entry.
  • The current OpenAI plugin directory UI does not show Superpowers as an available curated plugin.
  • However, the Codex App composer still showed two /brain results:
  • bare Brainstorming
  • Superpowers: Brainstorming

The bare Brainstorming entry opened this stale remote curated cache path:

~/.codex/plugins/cache/openai-curated-remote/superpowers/5.1.4/skills/brainstorming/SKILL.md

The stale remote bundle had:

~/.codex/plugins/cache/openai-curated-remote/superpowers/.codex-remote-plugin-install.json

with:

{
  "schema_version": 1,
  "remote_plugin_id": "plugins~Plugin_60aea7460bd4819199fd97a9553a5e12"
}

So the App composer was exposing a no-prefix skill from openai-curated-remote/superpowers, even though the user-visible installed plugin state only contained superpowers@superpowers-marketplace.

I also tried the documented disable direction:

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

but the remote curated cache could still be rehydrated. The only local workaround that stopped the duplicate composer entry was:

  1. codex plugin remove superpowers@openai-curated-remote --json
  2. delete the stale openai-curated-remote/superpowers bundle and stale remote catalog cache
  3. replace ~/.codex/plugins/cache/openai-curated-remote/superpowers with an immutable empty tombstone directory

Expected behavior:

  • Cached remote curated plugins that are not installed/enabled should not participate in composer skill suggestions or $skill resolution.
  • An explicit local config entry with enabled = false for superpowers@openai-curated-remote should take precedence over remote-installed/cache state.
  • codex plugin list, the App plugin UI, and composer skill suggestions should agree on whether a remote curated plugin is active.
  • If account-synced/remote curated plugin state is intentionally present, Codex should expose it clearly and provide a documented per-host disable path.

This seems related to #28443 and #26275 as well.

Allmight97 · 16 days ago

I can reproduce a materially consequential variant on macOS using ChatGPT Desktop 26.803.61601 and bundled codex-cli 0.147.0-alpha.6.5.

codex plugin list --json does not list GitHub as installed, and my ~/.codex/config.toml contains no GitHub plugin entry. Nevertheless, Codex materialized:

~/.codex/plugins/cache/openai-curated-remote/github/0.1.8-2841cf9749ae

and created .codex-remote-plugin-install.json on 2026-08-11, identifying remote plugin plugin_connector_1p_1a69035c238881919c4190932b2df699.

A subsequent Codex task injected github:yeet into the model-visible skill catalog. Its SKILL.md defaults PR creation to draft. The agent followed that instruction and opened a completed PR as draft even though I had never intentionally selected or installed that skill.

This is more than stale autocomplete: a plugin absent from the user-visible installed list supplied workflow instructions that changed external GitHub state.

Expected behavior:

  1. Only explicitly installed and enabled plugins may contribute active skill roots.
  2. Account-synced installations must appear consistently in the Desktop UI, codex plugin list, and configuration diagnostics.
  3. Connecting an app must not silently authorize its plugin skills.
  4. Every injected skill should expose why it is active, its installation source, and installation date.
  5. Uninstalling or disabling a remote plugin must prevent rehydration and skill injection.

Related reports: #28443, #26275, and #29450.

ChatGPT Desktop feedback ID containing the affected task telemetry: 019fe6ee-6dd7-72f3-be2f-b28b2f5001aa.

Mjones13 · 8 days ago

I reproduced a materially similar GitHub-plugin variant on 2026-08-20 in T3 Code on Linux.

Observed plugin state:

  • codex plugin list --json reported no installed or available plugins.
  • codex plugin marketplace list reported no configured marketplaces.
  • Nevertheless, the session skill catalog injected github:github from the remote curated cache snapshot github/0.1.9-5f7cd798dc99.
  • That cached skills/github/SKILL.md said that stage, commit, push, and PR creation each require separate explicit authorization and that requesting one action never authorizes the others.

Reproduction:

  1. Complete work on a clean non-default task branch with committed changes.
  2. Ask the agent naturally: Put up the PR for it and I'll review.
  3. The GitHub skill is selected from the remote curated cache.
  4. The agent treats the necessary branch push as separately unauthorized and stops to request another confirmation before it can create the PR.

This is stale relative to current openai/plugins main. The current GitHub routing skill classifies publish changes as the complete create/switch branch, stage, commit, push, and draft-PR workflow and routes it to skills/yeet/SKILL.md; yeet explicitly performs push followed by PR creation.

Impact:

  • A remotely injected cached instruction changed workflow behavior even though the plugin was absent from user-visible CLI plugin state.
  • Ordinary natural-language authorization for a complete PR-publishing workflow was narrowed by stale skill content, causing an unnecessary interruption.
  • The failure is not only stale discovery metadata; it changes how the agent interprets authorization for external GitHub operations.

Expected behavior:

  1. The skill catalog should only inject the active, observable plugin package selected for the session.
  2. codex plugin list, app/T3 plugin state, and model-visible skill roots should agree on plugin identity and version.
  3. A remote curated cache snapshot should not remain independently eligible after its source package has advanced.
  4. The active skill should expose its package identity/source clearly enough to diagnose version drift.
  5. After the corrected GitHub package is selected, a request to put up/open/create a PR should run the bounded publish workflow—including the necessary push and draft PR creation—without a redundant authorization round, while still not implying merge, force-push, or unrelated changes.

I did not edit or delete the cache. After the user clarified the intended compound authorization, the exact task branch was pushed and one draft PR was created successfully. The remaining issue is stale remote-plugin selection/distribution.