What version of Codex CLI is running?
codex-cli 0.142.5
What subscription do you have?
None
Which model were you using?
gpt-5.5
What platform is your computer?
Windows 11 Home (10.0.22631)
What terminal emulator and version are you using (if applicable)?
Windows Terminal + PowerShell 7.6.3
Codex doctor report
Omitted — the report contains no plugin/marketplace lifecycle diagnostics beyond what is described below; specific sections available on request.
What issue are you seeing?
I maintain a plugin installed from a git marketplace that declares SessionStart / UserPromptSubmit / Stop hooks. After new commits land in the marketplace repo, the first Codex session started afterwards reports hook exit 1 on every hook event, for the entire session — without any manual upgrade having been run. Starting another session makes the problem disappear.
Reading the source (main branch; behavior observed on 0.142.5), this looks like a lifecycle race between the startup marketplace auto-upgrade and hook declaration loading:
- On startup,
maybe_start_plugin_startup_tasks_for_config (codex-rs/core-plugins/src/manager.rs) unconditionally spawns the plugins-marketplace-auto-upgrade thread. When the git marketplace has new commits, it activates the new marketplace root and calls refresh_non_curated_plugin_cache_force_reinstall_detailed, which reinstalls the plugin cache even when the plugin version is unchanged. This part is directly visible in the source, and the auto-upgrade itself is confirmed on my machine: .codex-marketplace-install.json picked up new upstream revisions with no manual action.
- The reinstall path in
codex-rs/core-plugins/src/store.rs invalidates the previously active cache directory either way: a version bump ends with remove_old_plugin_versions deleting the old version directory (remove_dir_all); an unchanged version replaces the whole plugin cache entry via a backup/rename swap.
- Hook commands reference
${PLUGIN_ROOT}, which resolves to a versioned cache path (plugins/cache/<marketplace>/<plugin>/<version>/…). I could not pin down the exact expansion site in the source, but the observed behavior — the already-running session fails on every subsequent hook event while a freshly started session works — suggests the resolved path is captured when the plugin is loaded and not re-resolved for the lifetime of the session.
- If that reading is right, the failure sequence is: hooks load early against the old cache path, the background upgrade then deletes or replaces that path, and every later hook invocation runs
node <now-gone-path>/scripts/hook.mjs, which exits 1 (ERR_MODULE_NOT_FOUND) until the session ends. The next session resolves the already-upgraded cache and works — matching what I see.
Since the cache is shared, a newly started Codex process should likewise invalidate hooks of other sessions still running. I have not specifically reproduced this cross-process case; it follows from the same mechanism.
Windows note: the rename swap can presumably fail while a hook node process briefly holds file handles. Possibly related, one upgrade attempt left a stale marketplace-upgrade-* staging directory behind under .tmp/marketplaces/.staging/.
What steps can reproduce the bug?
Observed with a real plugin; a minimal setup should look like:
- Create a git marketplace with one plugin whose hook command references
${PLUGIN_ROOT}, e.g. node "${PLUGIN_ROOT}/scripts/hook.mjs" (script body irrelevant; exiting 0 is enough).
- Add the marketplace and install the plugin.
- Push a commit to the marketplace repo. Per the analysis above, bumping the plugin version should make the failure deterministic; content-only changes only expose the shorter swap window.
- Start a new Codex TUI session and trigger hook events.
- Hook invocations fail with exit 1 for the rest of the session; the next session works again.
What is the expected behavior?
A marketplace auto-upgrade should not invalidate hook commands of running sessions. Possible directions:
- re-resolve / reload hook declarations after the startup auto-upgrade completes (at least in the process that performed it), or
- resolve
${PLUGIN_ROOT} lazily at hook-execution time against the currently active version, or
- keep superseded version directories until no running session references them (grace period / in-use tracking) instead of deleting them right after activation.
Additional information
Timeline on my machine consistent with the analysis: hooks in a running session began failing a few hours after an upstream push, in the same window as an auto-upgrade attempt (the one that left the stale staging directory); the install metadata showed the new revision although no manual upgrade was run. Source references are against current main — happy to re-verify against a specific tag if useful.
What version of Codex CLI is running?
codex-cli 0.142.5
What subscription do you have?
None
Which model were you using?
gpt-5.5
What platform is your computer?
Windows 11 Home (10.0.22631)
What terminal emulator and version are you using (if applicable)?
Windows Terminal + PowerShell 7.6.3
Codex doctor report
Omitted — the report contains no plugin/marketplace lifecycle diagnostics beyond what is described below; specific sections available on request.
What issue are you seeing?
I maintain a plugin installed from a git marketplace that declares
SessionStart/UserPromptSubmit/Stophooks. After new commits land in the marketplace repo, the first Codex session started afterwards reportshook exit 1on every hook event, for the entire session — without any manual upgrade having been run. Starting another session makes the problem disappear.Reading the source (main branch; behavior observed on 0.142.5), this looks like a lifecycle race between the startup marketplace auto-upgrade and hook declaration loading:
maybe_start_plugin_startup_tasks_for_config(codex-rs/core-plugins/src/manager.rs) unconditionally spawns theplugins-marketplace-auto-upgradethread. When the git marketplace has new commits, it activates the new marketplace root and callsrefresh_non_curated_plugin_cache_force_reinstall_detailed, which reinstalls the plugin cache even when the plugin version is unchanged. This part is directly visible in the source, and the auto-upgrade itself is confirmed on my machine:.codex-marketplace-install.jsonpicked up new upstream revisions with no manual action.codex-rs/core-plugins/src/store.rsinvalidates the previously active cache directory either way: a version bump ends withremove_old_plugin_versionsdeleting the old version directory (remove_dir_all); an unchanged version replaces the whole plugin cache entry via a backup/rename swap.${PLUGIN_ROOT}, which resolves to a versioned cache path (plugins/cache/<marketplace>/<plugin>/<version>/…). I could not pin down the exact expansion site in the source, but the observed behavior — the already-running session fails on every subsequent hook event while a freshly started session works — suggests the resolved path is captured when the plugin is loaded and not re-resolved for the lifetime of the session.node <now-gone-path>/scripts/hook.mjs, which exits 1 (ERR_MODULE_NOT_FOUND) until the session ends. The next session resolves the already-upgraded cache and works — matching what I see.Since the cache is shared, a newly started Codex process should likewise invalidate hooks of other sessions still running. I have not specifically reproduced this cross-process case; it follows from the same mechanism.
Windows note: the rename swap can presumably fail while a hook
nodeprocess briefly holds file handles. Possibly related, one upgrade attempt left a stalemarketplace-upgrade-*staging directory behind under.tmp/marketplaces/.staging/.What steps can reproduce the bug?
Observed with a real plugin; a minimal setup should look like:
${PLUGIN_ROOT}, e.g.node "${PLUGIN_ROOT}/scripts/hook.mjs"(script body irrelevant; exiting 0 is enough).What is the expected behavior?
A marketplace auto-upgrade should not invalidate hook commands of running sessions. Possible directions:
${PLUGIN_ROOT}lazily at hook-execution time against the currently active version, orAdditional information
Timeline on my machine consistent with the analysis: hooks in a running session began failing a few hours after an upstream push, in the same window as an auto-upgrade attempt (the one that left the stale staging directory); the install metadata showed the new revision although no manual upgrade was run. Source references are against current
main— happy to re-verify against a specific tag if useful.