Title: Marketplace upgrades leave full git clones

Open 💬 5 comments Opened Jun 25, 2026 by Nod1l

What issue are you seeing?

Bug: Each marketplace "upgrade" of a git-sourced marketplace clones the
full repo (incl. .git history) into ~/.codex/.tmp/marketplaces/.staging/
marketplace-upgrade-XXXX, but the staging dir is never deleted after promotion.

Impact: Accumulated 1784 leftover clones = 277 GB on C: over ~3 days.
Only the single git marketplace (claude-mem) was affected; local marketplaces
don't clone. Each clone = 171 MB, of which 158 MB is .git history.

Two issues:

  1. Staging temp not cleaned up after upgrade.
  2. Full clone instead of shallow (--depth 1) re-downloads entire git history

every refresh.

Env: Codex CLI app version 26.616.71553, Windows 11.
High session churn (automated runs) multiplies the leak.

Workaround: manually delete ~/.codex/.tmp/marketplaces/.staging



### What steps can reproduce the bug?

## Steps to reproduce

1. Configure a git-sourced marketplace in ~/.codex/config.toml:
   [marketplaces.example]
   source_type = "git"
   source = "https://github.com/thedotmack/claude-mem.git"

2. Trigger a marketplace upgrade/refresh repeatedly (happens on session
   start; automated/looping sessions trigger it many times).

3. Inspect ~/.codex/.tmp/marketplaces/.staging/ — a new
   `marketplace-upgrade-XXXXXX` dir is created per upgrade.

4. After the upgrade completes, the staging dir is NOT deleted. Each one
   is a full clone (~171 MB; ~158 MB is .git history).

5. Over many upgrades they accumulate without cleanup.

## Observed
1784 leftover `marketplace-upgrade-*` dirs = 277 GB on C:, accumulated over
~3 days. Only the single git marketplace was affected (local marketplaces
don't clone).

## Note
Root cause inferred from the 1784 leftover clones + config (not captured
live). Two defects: (1) staging temp never cleaned after promote;
(2) full clone instead of shallow (--depth 1) re-downloads entire git
history every refresh.

## Env
Codex CLI app version 26.616.71553, Windows 11.

### What is the expected behavior?

1. After a marketplace upgrade is promoted, the temporary staging directory
   (~/.codex/.tmp/marketplaces/.staging/marketplace-upgrade-XXXXXX) is
   deleted automatically. No leftovers remain.
2. Stale or failed staging directories are cleaned up on the next startup,
   so they cannot accumulate across sessions.
3. Git-sourced marketplaces are fetched with a shallow clone (--depth 1)
   and/or updated in place (git fetch/pull on a cached copy) instead of a
   full re-clone of the entire history on every refresh.
Net result: marketplace refreshes use minimal, bounded disk space that does
not grow over time.

### Additional information

_No response_

View original on GitHub ↗

5 Comments

Nicolas0315 · 2 months ago

I put together a narrow patch for this on a fork branch:

What it changes:

  • git clone for configured git marketplace upgrades now uses --depth 1 for the default HEAD case and branch/tag-like refs.
  • It preserves full clone behavior for full SHA refs and full refs/... paths, so explicit commit/ref checkouts do not lose reachability.
  • The regression test verifies the installed marketplace has a shallow clone (.git/shallow, one reachable commit) and that a successful upgrade leaves no marketplace-upgrade-* staging dir behind.

Verification:

  • Windows local: just fmt
  • Windows local: just test -p codex-core-plugins marketplace_upgrade -> 12 passed
  • Windows local: cargo check -p codex-core-plugins
  • Windows local: git diff --check
  • SSH rtx4090: just test -p codex-core-plugins marketplace_upgrade -> 12 passed
  • SSH cyberagent-mac-m5max: fresh origin/main checkout + patch, cargo test -p codex-core-plugins marketplace_upgrade -> 12 passed

I also tried opening a draft PR against openai/codex, but GitHub returned:

GraphQL: Nicolas0315 does not have the correct permissions to execute `CreatePullRequest` (createPullRequest)

So I’m leaving the branch/compare here for maintainers.

oleksoleksoleks · 1 month ago

I hit the same incident class and filed a more detailed follow-up here: #30620.

Additional local evidence in that report: repeated marketplace-upgrade-* staging dirs under .tmp/marketplaces/.staging, each a full clone of the configured Git marketplace, accumulating to ~155G in one affected environment.

I also pushed a narrow cleanup fix branch: riverpilot:fix/marketplace-staging-prune.

That branch addresses the stale-staging cleanup side of this issue:

  • prunes abandoned .tmp/marketplaces/.staging/marketplace-upgrade-* dirs on the configured Git marketplace upgrade path
  • only removes old dirs with the marketplace-upgrade- prefix
  • leaves fresh staging dirs, unrelated staging entries, files, and installed marketplace roots untouched
  • keeps cleanup best-effort so cleanup failures do not block upgrades
  • runs before the “no configured marketplaces” early return, so old staging dirs can still be reclaimed if the marketplace config entry was removed, as long as the marketplace upgrade path is invoked

Nicolas’s branch, Nicolas0315:codex/marketplace-shallow-upgrades, addresses the other side: reducing future clone size by using --depth 1 for safe HEAD/branch/tag-like marketplace clones.

I think these are complementary rather than equivalent:

  • stale-prune bounds/reclaims orphaned staging dirs from crashed/killed/interrupted processes
  • shallow clone reduces the size/network cost of future upgrade clones

One nuance: if a successful promotion is directly observed leaving its marketplace-upgrade-* dir behind, that would be an immediate cleanup bug. From the current code path, normal successful promotion should move/drop the temp dir; the durable leak I reproduced is abandoned staging dirs that are not later pruned.

Clay996 · 16 days ago

I reproduced this incident class and found a second trigger beyond orphaned TempDirs: multiple Codex processes can read the same stale marketplace revision, then each perform the same upgrade even after another process has already activated it. In the affected Windows environment, staging grew from 45 to 83 directories (about 9.8 GiB total), with a new full marketplace clone appearing roughly every five minutes.

I prepared a bounded fix on a fork branch:

The patch combines the two existing partial directions in this issue with the missing correctness and resource bounds:

  • re-checks the active revision after acquiring the upgrade lock, making stale snapshots idempotent;
  • uses per-marketplace OS locks plus a global two-upgrade cap across processes;
  • resolves branch, tag, and SHA refs and fetches only the exact shallow object needed;
  • activates atomically and rolls back on failure;
  • records staging attempt metadata and recovers only abandoned attempts;
  • explicitly cleans staging with bounded Windows retries;
  • enforces 1 GiB per attempt and 2 GiB aggregate staging budgets;
  • caps captured child output at 64 KiB and kills the process tree on timeout;
  • applies bounded failure backoff, including remote-resolution failures.

Verification on the branch:

  • marketplace upgrade suite: 25/25 passed;
  • full codex-core-plugins crate: 408/408 passed, with one pre-existing environment-only WSL Git compatibility test skipped;
  • just fix -p codex-core-plugins: clean;
  • Rust formatting: clean.

Per the repository's invitation-only contribution policy, I have not opened an unsolicited PR. If maintainers want this broader fix, please invite a PR and I will submit the branch with the issue linked.

nviraj · 16 days ago

I encountered the same issue on Windows with Codex CLI 0.147.0, and wanted to add another data point because the behavior I observed may help distinguish successful-upgrade cleanup from abandoned staging cleanup.

Environment

  • Codex CLI: codex-cli 0.147.0
  • OS: Windows
  • Shell: PowerShell
  • CODEX_HOME: not set at process, user, or machine scope
  • Codex data directory: default ~\.codex
  • Marketplace names and repository/project details omitted/redacted

What I observed

Under:

~\.codex\.tmp\marketplaces\.staging

I found well over 100 directories with names of the form:

marketplace-upgrade-XXXXXX

The oldest one I observed dated back to early June, with many more accumulating through July and August.

There were periods where new directories appeared only minutes apart, and in some cases multiple directories had timestamps only seconds apart.

The accumulated staging directory was approximately:

5.14 GB

None of the active marketplace roots reported by:

codex plugin marketplace list

pointed into any of these marketplace-upgrade-* directories.

Cleanup / validation test

To avoid deleting potentially active state, I:

  1. Fully exited Codex/ChatGPT processes.
  2. Renamed .staging to a temporary backup.
  3. Verified that the configured marketplaces still appeared normally with:
codex plugin marketplace list
  1. Ran:
codex plugin marketplace upgrade

The upgrade completed successfully:

Upgraded 1 marketplace(s).
  1. Checked the marketplace directory afterward.

During this fresh upgrade, Codex recreated:

~\.codex\.tmp\marketplaces\.staging

and updated the marketplace successfully.

Crucially, after the successful upgrade completed, the newly created .staging directory contained no leftover marketplace-upgrade-* directories.

I then removed the old staging backup and recovered approximately 5.14 GB.

Additional stale backup

I also found an older sibling directory with a name of the form:

~\.codex\.tmp\marketplaces\marketplace-backup-XXXXXX

It was roughly a month old, was not referenced by any active marketplace root, and remained present across successful marketplace operations. I removed it separately after verifying it was not in use.

What this seems to suggest

At least in my case, a normal, manually triggered successful marketplace upgrade cleaned up its current staging directory correctly.

The disk growth therefore appears more consistent with staging directories being abandoned by earlier upgrade attempts/processes and never being reclaimed afterward, rather than every successful upgrade deterministically leaking its temporary directory.

That seems consistent with the distinction mentioned above between:

  • immediate cleanup after a successful promotion; and
  • stale/abandoned marketplace-upgrade-* directories from interrupted, failed, concurrent, or otherwise incomplete upgrade attempts not being pruned later.

The timestamp pattern was notable because there were clusters of repeated staging directories created at short intervals over extended periods, rather than just one or two isolated leftovers.

Expected behavior

Even when an upgrade is interrupted, fails, or its creating process exits unexpectedly, stale directories such as:

~\.codex\.tmp\marketplaces\.staging\marketplace-upgrade-*

should eventually be reclaimed safely—for example during a subsequent startup or marketplace upgrade—so disk usage remains bounded.

It would also be useful if stale marketplace-backup-* directories were subject to similarly conservative cleanup when they are no longer referenced.

Happy to provide additional diagnostics if there is a specific command or metadata that would help, provided it can be shared with user paths / marketplace details redacted.

jerldev · 13 days ago

I can confirm this issue on Linux with a public Git-backed marketplace.

Environment

  • Codex CLI: codex-cli 0.147.0
  • OS: LMDE 7, Linux x86_64
  • Git marketplace: https://github.com/Gentleman-Programming/engram.git

Observed disk growth

First occurrence:

  • 413 marketplace-upgrade-* directories
  • approximately 31 GB under ~/.codex/.tmp/marketplaces/.staging

After deleting those confirmed orphaned staging directories, the problem recurred within roughly 18 hours:

  • 743 marketplace-upgrade-* directories
  • approximately 56 GB in staging
  • 739 readable clones had the same Engram Git remote; the remaining directories were incomplete
  • creation timestamps ranged from 2026-08-13 19:58 through 2026-08-14 14:15, frequently about one new clone per minute
  • the root filesystem reached 99% usage with only 6.4 GB free

The active marketplace root remained valid, and Codex's marketplace metadata advanced its last_updated and last_revision values. None of the active marketplace roots reported by codex plugin marketplace list --json pointed into the staging directories.

Cleanup and workaround

I removed only the orphaned marketplace-upgrade-* directories after verifying the active marketplace root was elsewhere. This reduced ~/.codex from approximately 57 GB to 958 MB and restored free disk space from 6.4 GB to 62 GB.

As a temporary mitigation, I changed this Codex-only marketplace registration from a Git source to a local source containing the same verified revision. The plugin remained installed and enabled, and no new staging clone appeared during an immediate observation window longer than the previous approximately one-minute creation cadence.

This looks consistent with abandoned or concurrent Git marketplace upgrade attempts not being reclaimed, rather than normal plugin/session storage growth.