fix(marketplace): prune stale upgrade staging directories

Open 💬 1 comment Opened Jun 29, 2026 by riverpilot

Summary

Marketplace Git auto-upgrade can leave full cloned repositories under:

$CODEX_HOME/.tmp/marketplaces/.staging/marketplace-upgrade-*

Those dirs are expected to be temporary upgrade staging dirs, but if a Codex process is killed or crashes while an upgrade is in flight, tempfile::TempDir cleanup does not run and the staged clone can be left behind.

Observed impact

In one affected environment, .staging contained more than 1,000 marketplace-upgrade-* directories, each a full clone of the same marketplace repository, consuming about 155G total. The installed marketplace cache itself was only about 138M.

Healthy layout should be roughly:

marketplaces/
  <marketplace>/
  .staging/        # empty, or only brief active temp dirs

Affected layout was effectively:

marketplaces/
  <marketplace>/
  .staging/
    marketplace-upgrade-AAAAAA/
    marketplace-upgrade-BBBBBB/
    marketplace-upgrade-CCCCCC/
    ...

Why this can leak

The marketplace upgrade path creates staging dirs with tempfile::Builder and a marketplace-upgrade- prefix. Normal Rust error paths should drop the TempDir and remove the staged clone, but process death before Drop runs leaves the directory behind.

A local repro with a disposable CODEX_HOME confirmed that killing the process during a marketplace clone leaves a marketplace-upgrade-* staging dir behind, and later upgrade attempts do not prune the orphan.

Proposed fix

Proposed fix branch: riverpilot:fix/marketplace-staging-prune

The proposed patch:

  • only scans $CODEX_HOME/.tmp/marketplaces/.staging
  • only removes entries named marketplace-upgrade-*
  • only removes directories, not files or symlinks
  • only removes dirs older than 24 hours
  • logs warnings and continues on cleanup errors
  • runs before the “no configured marketplaces” early return, so stale dirs can still be reclaimed when the marketplace config entry has been removed, as long as the marketplace upgrade path is invoked

It does not add retry/backoff changes or cross-process locking.

Tests in proposed fix

The branch adds tests for:

  • stale marketplace-upgrade-* directories are removed
  • fresh marketplace-upgrade-* directories are kept
  • stale wrong-prefix directories are kept
  • prefix-matching files are kept
  • installed marketplace roots are kept
  • stale staging cleanup still runs when no Git marketplaces are configured, once the marketplace upgrade path is invoked

Local validation

On the proposed branch:

cargo fmt --package codex-core-plugins
cargo test -p codex-core-plugins marketplace_upgrade -- --nocapture

The targeted marketplace upgrade suite passed.

Note

PR creation from the fork is currently blocked by repository owner restrictions, so I am filing this issue with the branch/compare link instead.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗