Windows Codex Desktop persists volatile plugin cache hash paths in sessions, causing older threads to lose skills after plugin cache updates

Open 💬 9 comments Opened May 30, 2026 by lengmingz
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex Desktop on Windows appears to persist absolute SKILL.md paths under volatile plugin cache hash directories into long-lived session context. After the plugin cache updates and the previous hash directory is removed, older or running sessions can fail to load skills, repeatedly report that skills are missing, and reconnect several times before failing.

This does not appear to be user-authored configuration. The affected paths are generated/injected by Codex as part of the available-skills/session context.

Environment

  • OS: Windows
  • Product: Codex Desktop
  • Plugin family observed: openai-curated/superpowers, openai-curated/figma, and openai-bundled/browser
  • Current observed real Superpowers/Figma cache hash: fef63ecf
  • Previous observed bridge target hash: acdd3141
  • Older session paths observed: 719ed655, 9b3c8689
  • Example failed stream request ID shown by the app: a544bbba-7fb9-4e58-937c-927e0f7a617a

Symptoms

  • Older sessions say skills such as subagent-driven-development cannot be found.
  • Sessions repeatedly show reconnect messages before eventually failing.
  • The skill files still exist under the latest cache hash, but old session paths point to removed hash directories.
  • Recreating compatibility junctions from old hash paths to the current hash immediately restores SKILL.md reads.

Evidence

Representative path from an older session, redacted:

C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\719ed655\skills\subagent-driven-development\SKILL.md

Before the local workaround, old session paths were stale:

Test-Path "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\719ed655\skills\subagent-driven-development\SKILL.md"
# False

Test-Path "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\9b3c8689\skills\subagent-driven-development\SKILL.md"
# False

The same skill existed under the current real plugin cache hash:

Test-Path "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\fef63ecf\skills\subagent-driven-development\SKILL.md"
# True

Test-Path "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\fef63ecf\skills\systematic-debugging\SKILL.md"
# True

After creating local compatibility junctions, old paths immediately became readable again:

# Examples of non-destructive compatibility junctions created locally:
# superpowers\acdd3141 -> superpowers\fef63ecf
# figma\acdd3141 -> figma\fef63ecf
# browser\26.519.81530 -> browser\26.527.30818

Test-Path "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\719ed655\skills\subagent-driven-development\SKILL.md"
# True

Get-Content "C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\719ed655\skills\subagent-driven-development\SKILL.md" -TotalCount 3
# ---
# name: subagent-driven-development
# description: Use when executing implementation plans with independent tasks in the current session

This suggests the underlying skills were not removed. The persisted cache-hash path became stale.

Expected behavior

Durable session state should persist stable skill references, not absolute paths under volatile plugin cache hashes.

For example, session state could store a semantic reference such as:

skill://openai-curated/superpowers/subagent-driven-development

or structured data such as:

{
  "source": "openai-curated",
  "plugin": "superpowers",
  "skill": "subagent-driven-development"
}

On resume or turn start, Codex should resolve that reference through the current plugin registry.

Actual behavior

Older sessions appear to retain paths like:

C:\Users\<redacted>\.codex\plugins\cache\openai-curated\superpowers\<hash>\skills\<skill>\SKILL.md

When <hash> changes and the old cache directory is removed, session skill loading breaks even though the skill exists under the current cache hash.

Suggested fix

  • Do not serialize plugin cache hash paths into session/system context.
  • Store stable semantic skill references instead.
  • Regenerate the available-skills list from the current plugin registry when resuming a thread.
  • Add a persistence guard that rejects or rewrites paths matching .codex\plugins\cache\...\<hash>\skills\... before they enter durable session state.
  • Optionally maintain a stable per-plugin current pointer as a compatibility layer for file-path consumers.

Additional notes

The local junction workaround confirms this is path-staleness rather than skill deletion, but it is not a durable product fix because plugin cache hashes can change again on update.

View original on GitHub ↗

9 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #24390

Powered by Codex Action

lengmingz · 1 month ago

I prepared a fix branch here:

https://github.com/lengmingz/codex/tree/fix/plugin-cache-retain-superseded-skill-paths

Compare URL:

https://github.com/openai/codex/compare/main...lengmingz:codex:fix/plugin-cache-retain-superseded-skill-paths

Commit:

889e25c Keep old plugin cache versions readable

Approach:

  • retain superseded plugin cache version directories so already-started or resumed sessions can keep reading previously injected SKILL.md paths
  • add a .active-version marker so the active plugin version is explicit instead of inferred from retained version directory names
  • replace only the active version directory on reinstall, preserving older version directories that may still be referenced by existing sessions

I tried to open a PR from the fork, but GitHub rejected both gh pr create and the API call with permission errors from this account/session. Local tests were not run because this Windows environment does not have cargo, rustc, just, or bazel on PATH.

lengmingz · 1 month ago

I pushed a proposed fix branch here after local verification:

Summary of the proposed fix:

  • Retain superseded plugin cache version directories so older sessions that captured absolute skill paths keep working after plugin cache updates.
  • Add a per-plugin .active-version marker so the current version remains unambiguous while old local/hash directories are retained.
  • Update store and refresh tests to cover retained old paths, marker selection, and active-version reinstalls.

Local verification on Windows:

  • just fmt
  • just test -p codex-core-plugins (190 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; reported an existing manifest.rs large_enum_variant warning)

I attempted to open the upstream PR from this fork branch via both gh pr create and the GitHub connector, but GitHub rejected the create-pull-request API call with permission errors (CreatePullRequest / Resource not accessible by integration). The branch is available at the compare link above.

lengmingz · 1 month ago

Update after reviewing #24390, especially the cache-invalidation analysis in https://github.com/openai/codex/issues/24390#issuecomment-4577771198:

I updated the proposed fix branch to address both layers of the problem:

Changes now included:

  1. Compatibility layer for already-injected absolute paths:
  • Retain superseded plugin cache version directories instead of deleting them during cache refresh/reinstall.
  • Add a per-plugin .active-version marker so the active version is explicit while older cache-version dirs remain readable.
  1. Root-cause cache invalidation from #24390:
  • Include configured/remote plugins' active cache versions in PluginsManager's cached PluginLoadOutcome key, not just the effective config TOML version.
  • This prevents plugins_for_config from returning stale effective_plugin_skill_roots after the active plugin cache version changes under the same config.
  • Route curated startup cache refreshes through the existing effective-plugins-changed callback so app-server clears both plugin and skill caches.
  1. Regression coverage:
  • Added a test that loads a configured plugin at 1.0.0, updates the active cache version to 2.0.0 without clearing the manager cache, then verifies the next plugins_for_config call returns the 2.0.0 skill root.
  • Updated refresh/store tests to expect retained old cache dirs plus .active-version selection.

Local verification on Windows:

  • just fmt
  • just test -p codex-core-plugins (191 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; reported an existing manifest.rs large_enum_variant warning)

I retried PR creation after this update, but GitHub still rejects this account/session's API call with:

GraphQL: lengmingz does not have the correct permissions to execute `CreatePullRequest`

The compare link above should be ready for a maintainer to open or cherry-pick.

lengmingz · 1 month ago

Additional handoff artifact: since GitHub still rejects creating the upstream PR from this account/session, I opened a fork-local mirror PR so the patch has a stable PR-style diff/review page:

The mirror PR is draft and exists only as a review/handoff artifact; it targets the same commit described above and verified with:

  • just fmt
  • just test -p codex-core-plugins (191 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; existing manifest.rs large_enum_variant warning only)
lengmingz · 1 month ago

Update: the fork-local mirror PR is now marked ready for review (no longer draft):

It still targets the same verified commit: 6c2c94daf4026f526465cc4d974348091fb45488.

lengmingz · 1 month ago

Maintenance update: rebased the handoff branch onto current openai/codex@main after #25318 landed.

Fresh verification after rebase:

  • just fmt
  • just test -p codex-core-plugins (191 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; existing manifest.rs large_enum_variant warning only)
lengmingz · 1 month ago

Maintenance update: rebased the handoff branch onto current openai/codex@main (3b7334d099b339e7b18418a0cf7ac34e7bed2e43).

Fresh Windows verification after rebase:

  • just fmt
  • just test -p codex-core-plugins (191 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; existing core-plugins/src/manifest.rs large_enum_variant warning only)

I retried creating the upstream PR, but GitHub still rejects this account/session with CreatePullRequest permission errors.

lengmingz · 1 month ago

Maintenance update: rebased the handoff branch onto current openai/codex@main (9756316d89968945212cd5f958b2b972c77c9e09) after upstream touched core-plugins/src/manager_tests.rs.

Fresh Windows verification after rebase:

  • just fmt
  • just test -p codex-core-plugins (192 passed; bench smoke compiled and started)
  • just fix -p codex-core-plugins (passed; existing core-plugins/src/manifest.rs large_enum_variant warning only)

I retried creating the upstream PR, but GitHub still rejects this account/session with CreatePullRequest permission errors.