openai / openai/codex

[Windows][26.901.1978.0] `cua_node` `rename_staging` EPERM loops indefinitely, freezes desktop UI, and consumes ~59 GB

Open
#42,484 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug performance windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Codex version

  • Codex desktop: 26.901.1978.0 (Microsoft Store/MSIX, x64)
  • Bundled Codex CLI: 0.153.0-alpha.5
  • A similar relocation failure also occurred after updating version 26.820.7780.

Environment

  • Windows 11 Pro 25H2, build 26200.8457, AMD64
  • Runtime root: %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node
  • Affected runtime content ID: ad3b5049246cde44

Description

After an app update, Codex desktop starts but becomes extremely slow and eventually enters Windows' "Not responding" state. This is not ordinary renderer lag: the desktop main process repeatedly tries to materialize its bundled Node runtime and fails at the final staging-directory rename with Windows EPERM.

Each failed attempt creates another large .staging-* directory. In this incident, the loop produced 591 staging directories and consumed 58.96 GB before remediation. The retries were approximately three seconds apart. Windows also recorded MoAppHang for the app.

Sanitized log evidence

event=bundled_executable_relocation_failed
destinationPath=%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\ad3b5049246cde44
errorCode=EPERM
operation=rename_staging
executableName=node.exe   # also observed for node_repl.exe
originalError={"errno":-4048,"code":"EPERM","syscall":"rename",
  "path":"%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\.staging-ad3b5049246cde44-<uuid>",
  "dest":"%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\ad3b5049246cde44"}

The relocation failure is followed by errors equivalent to:

Unable to locate the Codex CLI binary / bundled Node runtime

Reproduction sequence

  1. Update Codex desktop on Windows and launch it.
  2. The app reports an Electron/PATH-related startup error; retrying can eventually open the UI.
  3. The UI then freezes or becomes unresponsive.
  4. Observe %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node while the app is running.
  5. A new .staging-ad3b5049246cde44-* directory appears roughly every three seconds, while the finalized ad3b5049246cde44 directory never appears.
  6. Disk usage and main-process blocking continue to grow until Codex is terminated.

Implementation-level findings

Inspection of the installed desktop bundle indicates this failure is amplified by the materialization logic:

  • The app recursively copies the bundled runtime synchronously, then calls a synchronous directory rename from staging to the content-addressed final directory.
  • If the rename throws, staging cleanup is attempted, but any cleanup failure is swallowed.
  • The resolved-runtime cache is populated only after successful finalization, so a transient failure is not remembered.
  • Separate startup consumers request node.exe, node_repl.exe, and node_modules; after each failure they can re-enter the full copy-and-rename path.
  • There is no bounded retry, exponential backoff, lock coordination, or failure circuit breaker for transient EPERM.
  • Because recursive copy/rename work is synchronous in the desktop main process, the retry loop directly contributes to UI hangs.

This explains both the repeated staging-directory creation and the user-visible freeze. The initial process that briefly held the file/directory handle cannot be proven retroactively without ProcMon/ETW data, but the persistent app hang and disk exhaustion are caused by the unbounded failure/retry behavior.

Recovery verification

With Codex fully stopped, constructing the complete runtime in a single staging directory and atomically renaming it to ad3b5049246cde44 succeeded. After restarting:

  • the staging-directory count remained at 0;
  • bundled Node (v24.19.0) was usable;
  • Codex processes remained responsive;
  • no new hang/crash events appeared;
  • the desktop UI became immediately smooth again.

Deleting the orphaned staging directories recovered 58.96 GB. No Codex settings or project data were removed.

Expected behavior

  • Treat EPERM during final rename as a transient Windows sharing/scan condition and retry the rename itself with bounded exponential backoff and jitter.
  • Coordinate concurrent runtime requests so only one materialization is in flight per content ID.
  • Never repeat the entire synchronous recursive copy every few seconds from the main process.
  • Surface cleanup failures and reliably remove orphaned staging directories on the next launch.
  • Add a retry/circuit-breaker limit so runtime relocation cannot indefinitely freeze the UI or exhaust the system drive.

Related reports

  • #41850 — Windows runtime staging does not finalize after a clean reset
  • #41654 — Windows desktop update regressions involving protected runtime relocation

Only sanitized excerpts are included here; raw logs may contain local paths and account/session metadata.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the desktop main process's bundled-runtime materialization logic, especially the synchronous staging-directory rename and cleanup path described in the issue. Reproduce the Windows EPERM failure, then verify bounded rename retries, coordinated requests, surfaced cleanup failures, and a circuit breaker prevent repeated staging directories, disk exhaustion, and UI freezing.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, node.js
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.