Codex Desktop `review-summary` spawns thousands of `git hash-object` processes when nested repositories are present

Open 💬 6 comments Opened Jun 11, 2026 by 0xdevalias
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Feedback ID / Bug Report ID: 019eb57d-d318-78f2-8c45-76dea130046d

What version of the Codex App are you using (From “About Codex” dialog)?

Version 26.608.12217 • Released Jun 9, 2026

What subscription do you have?

Irrelevant

What platform is your computer?

Darwin 25.3.0 arm64 arm

What issue are you seeing?

Codex Desktop can spawn thousands of concurrent git hash-object processes while loading repository review state for a thread.

In one captured reproduction, the main Codex GUI process spawned exactly 5,042 direct children over approximately 14 seconds. Every child used this command shape:

git -c core.hooksPath=/dev/null -c core.fsmonitor= \
  hash-object --no-filters -- <PATH>

All 5,042 children exited and temporarily remained as zombies under the main Codex process:

18:36:43  Codex zombies:   20
18:36:48  Codex zombies: 1,403
18:36:53  Codex zombies: 3,412
18:36:58  Codex zombies: 5,042
18:37:00  Codex zombies: 5,042
18:37:01  Codex zombies:     0

This temporarily consumed almost half of the macOS per-user process limit of 10,666.

I inspected the installed Desktop app.asar. The packaged Git worker's review-summary path:

  1. Collects paths requiring content revisions.
  2. Attempts one bulk git hash-object --no-filters -- <all paths> command.
  3. If that command fails or returns the wrong number of hashes, falls back to the equivalent of:
await Promise.all(
  paths.map(path => hashObject([path]))
);

The fallback has no concurrency limit.

I reconstructed the original argument set from the process trace:

unique paths:       5,042
regular files:      5,039
directories:            3
missing paths:           0
bulk exit status:      128
stdout hashes:           24
stderr:            fatal: Unable to hash (null)

The three directories were untracked nested Git repositories containing their own .git metadata. Each independently caused git hash-object to exit 128.

Therefore, three unhashable entries caused the application to retry all 5,042 paths concurrently.

The hashing path also does not pass the outer review request's abort signal into the Git helper. Switching away from the thread does not cancel the fallback once it starts.

What steps can reproduce the bug?

Observed reproduction:

  1. Open an outer Git repository containing:
  • thousands of visible untracked/generated files; and
  • one or more untracked nested Git repositories, each containing its own .git directory.
  1. Open a Codex thread associated with that repository.
  2. Switch away from and back to the thread, causing Desktop to refresh its repository review summary.
  3. If necessary, open a second Codex window and switch among threads associated with the repository.
  4. Monitor direct zombie children of the main Codex process:
while true; do
  CODEX_PID="$(
    pgrep -f '/Applications/Codex.app/Contents/MacOS/Codex' |
      head -1
  )"

  printf "%s  " "$(date '+%Y-%m-%d %H:%M:%S')"

  ps -axo ppid=,stat=,user= |
    awk -v pid="$CODEX_PID" -v user="$USER" '
      $2 ~ /^Z/ { total_zombies++ }
      $1 == pid && $2 ~ /^Z/ { codex_zombies++ }
      $3 == user { user_processes++ }
      END {
        printf "pid=%s  codex_zombies=%d  total_zombies=%d  user_processes=%d\n",
          pid,
          codex_zombies + 0,
          total_zombies + 0,
          user_processes + 0
      }
    '

  sleep 1
done

For prospective process identification:

OUT="$HOME/Desktop/codex-process-events-$(date '+%Y%m%d-%H%M%S').jsonl"

sudo /usr/bin/eslogger \
  --select /Applications/Codex.app \
  --select "$HOME/.codex" \
  exec fork exit \
  > "$OUT"

The JSONL contains local paths and command arguments and must be sanitized before sharing.

Two windows are not known to be required. They made the trigger easier to reproduce in this capture.

No session ID, token-limit usage, or context-window usage appears applicable because this is a Desktop Git-worker/repository-state operation.

What is the expected behavior?

Repository review-summary calculation should not create one concurrent child process per path.

Codex Desktop should:

  • recognize nested-repository/gitlink entries and avoid passing directory paths to blob hashing;
  • batch or otherwise bound git hash-object operations;
  • avoid an all-path concurrent fallback when one item fails;
  • pass request cancellation through to all Git operations;
  • serialize or deduplicate overlapping review-summary work for the same repository;
  • degrade gracefully when a repository contains a very large visible untracked tree.

A malformed or unhashable path should affect only that path, not cause thousands of subprocesses to be launched.

Additional information

Installed bundle details:

Desktop app:       26.608.12217 (build 3722)
Bundled backend:   codex-cli 0.138.0-alpha.7
app.asar SHA-256:  4545a5b9cc1e244254f444a611f21c49f4f997cb158bab7a2d7397f6954079df

The relevant packaged code is in .vite/build/worker.js.

Minified call path:

review-summary
  -> E5 / e5 / r5
  -> X8
  -> a5
  -> c5 / h5
  -> b5 / x5

Relevant identifiers:

b5 / x5   bulk hash plus unbounded single-path fallback
h5        revision calculation caller
I8 / R8   temporary-index staging using 1,024-path chunks
U8 / W8   working-tree tree construction
jQ / MQ   child_process.spawn and close-event handling

The same worker already stages untracked paths sequentially in chunks of 1,024 while constructing its temporary Git index. The process trace showed those batches, followed by write-tree, three metadata diffs, and then the 5,042-process hash fallback.

Related issues:

  • #25744
  • main-GUI-owned zombie accumulation and process-table exhaustion
  • #27382
  • Git-worker failures with nested repositories and large directory trees
  • #20933
  • passive review-summary Git fanout in large/untracked repositories
  • #18099
  • nested repositories breaking review-pane behavior

This report identifies a narrower, deterministic implementation defect than those existing reports.

Previous process-exhaustion evidence:

Raw process traces contain local paths and are not attached publicly. Sanitized extracts can be provided if needed.

See Also

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 2 months ago

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

  • #27382

Powered by Codex Action

0xdevalias · 2 months ago
Potential duplicates detected. Please review them and close your issue if it is a duplicate.

I reviewed #27382. It is closely related, but not an exact duplicate.

#27382 reports a Git-worker V8 heap OOM/SIGABRT. This issue identifies a distinct, deterministic subprocess-fanout defect in review-summary, with different symptoms and remediation.

The defect here may contribute to the pressure observed in #27382, so the issues should remain cross-linked.

MisterRound · 2 months ago

Additional Windows + WSL reproduction on current Codex Desktop.

Environment:

  • Windows 11 + WSL2 Ubuntu
  • Codex Desktop package: OpenAI.Codex_26.609.9530.0_x64__2p2nqsd0c76g0
  • App-server reported: 0.140.0-alpha.2
  • Desktop WSL mode enabled
  • Workspace path inside WSL, not /mnt/c

Observed impact:

  • Codex Desktop became system-wide disruptive: mouse / Alt-Tab stutter, high VmmemWSL, and Desktop UI delays.
  • Task Manager showed VmmemWSL around 9 GB, Codex active, plus Defender/MDE activity.
  • Inside WSL, memory was not actually exhausted; much of VmmemWSL appeared to be cache/reservation.
  • WSL then entered a session/interop failure pattern with thousands of:
  • UtilAcceptVsock waiting/accept failures
  • SessionLeader accept4 failed 110
  • A 10 minute sample contained 7,644 UtilAcceptVsock / SessionLeader errors.
  • WSL accumulated 407 Relay processes.

Codex log evidence:

  • Current Desktop log showed review-summary Git work against a WSL repo with a large generated/untracked tree.
  • Counted 4,177+ git hash-object --no-filters / review-summary related log entries in the active session.
  • Commands included very large argument sets, e.g. git add -- ... with argsCount=1026 and hash-object --no-filters over thousands of generated paths.
  • Many per-file hash-object operations ran for about 136-176s and failed with exitCode=4294967295 / command_failed.
  • This started during Desktop background/local conversation git summary work, not from an explicit user shell command.

Local mitigation:

  • Added local-only .git/info/exclude entries for generated/browser/report artifact directories.
  • Expanded git status surface dropped from 2,212 paths to 358 paths.
  • For another important WSL project using .repo.git, the real git status surface dropped from 15,884 paths to 813 after excluding generated artifact directories.

Interpretation:

This appears to be the same review-summary / hash-object implementation class as this issue, with Windows/WSL-specific consequences:

  • large generated/untracked trees cause expensive review-summary hashing;
  • Desktop background Git work can fan out enough subprocess/interop activity to wedge WSL;
  • WSL then reports Relay buildup and UtilAcceptVsock / SessionLeader failures;
  • VmmemWSL growth is mostly cache/IO side effect, not a normal app RSS leak.

Expected behavior:

  • review-summary should cap/debounce work for large dirty repos;
  • avoid one subprocess per path or unbounded fallback fanout;
  • respect generated/ignored/dependency directories aggressively;
  • cancel in-flight Git review work when the thread/view changes;
  • degrade to "too many untracked/generated files to summarize" instead of saturating WSL.
0xdevalias · 2 months ago

Some potentially relevant sounding PRs from v0.140.0 (at the very least, they seem git related/etc):

suiyuebaobao · 1 month ago

The review-summary plus thousands of git hash-object processes reported here is especially close to the Changes/Review trigger I reproduced.

I published a single-file Windows launcher for the original Microsoft Store/MSIX Codex app:

It starts Codex with a process-scoped GIT_DIR=NUL. On my machine, the stable trace changed from 247 new git.exe and 137 new taskkill.exe processes per 10 seconds to 0 and 0 over 15 seconds; WMI Provider Host fell from about 6.6% to 0.9%.

Usage: fully exit Codex from the Windows system tray, then run the script.

This is an unofficial workaround, not an upstream fix. It deliberately disables or limits Review, Changes, branch detection, commit, and other Git-backed Codex features. It does not patch Codex, modify repositories or Git configuration, write system environment variables, require elevation, terminate processes, or remove chat history. Launching Codex normally restores Git integration.

nguyenphutrong · 22 days ago

Still reproducible on macOS/Apple Silicon with app version 26.730.61639
(bundle 6234).

Observed:

  • 7,305 processes in the app process tree
  • 7,194 zombie children under the main app PID
  • 7,975 / 8,000 per-user process slots used
  • zsh and posix_spawn failing with:

"Resource temporarily unavailable"

Quitting the app immediately reduced the zombie count to 0.
The issue reappears after relaunching the app.