Repository navigation
[Windows]PerformanceCUA runtime materializer retries 4,680 doomed encrypted copy operations, causing ~8-minute first launch after updates #41822
Description
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.825.6671.0 Microsoft Store / MSIX installation
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Windows 11 x64 Microsoft Store / MSIX installation
What issue are you seeing?
After a Codex Desktop update, the first launch can remain headless for approximately 8 minutes before the Renderer appears.
I investigated the full startup timeline and then reproduced the CUA runtime materialization logic independently.
The delay is dominated by the Windows CUA Node runtime relocation step:
- AppX Stage: ~5.9 s
- AppX Register: ~5.1 s
- CUA runtime materialization: 485 s
- Runtime completion → first Renderer: ~2 s
- Renderer → app-server: ~2 s
The runtime contains:
- 4,680 files
- 833 subdirectories
- 334,374,010 bytes / 318.9 MiB
The important finding is that the delay is not caused by the amount of data being copied.
The Electron main-process materializer performs a synchronous, serial, depth-first copy of every file.
For each file it first calls:
copyFileSync(source, destination)
The MSIX source files carry the Windows Encrypted / Application Protected attribute.
On this machine, every one of the 4,680 copyFileSync calls fails with the Windows encrypted-copy failure path (errno=-4094, code=UNKNOWN; corresponding behavior is consistent with ERROR_ENCRYPTION_FAILED).
The code then falls back to:
writeFileSync(destination, readFileSync(source))
This fallback succeeds.
However, the materializer does not remember that the native copy path has already failed for this source tree. It repeats the same doomed copyFileSync attempt for every subsequent file.
So the effective algorithm is:
for each of 4,680 files:
try copyFileSync()
-> fails on Application Protected / encrypted MSIX source
readFileSync()
writeFileSync()This happens synchronously on the Electron main process before the Renderer is created.
Reproduction / benchmark
I reproduced the same file tree outside the production runtime without modifying the installed Codex package or the real runtime.
All successful copies contained the same:
- 4,680 files
- 833 directories
- 334,374,010 bytes
Results:
Method | Time -- | -- Real Codex first materialization | 485.0 s Exact reproduction of Codex materializer behavior | 429.685 s Node serial readFile + writeFile only | 19.195 s Node bounded parallel read/write, concurrency 32 | 9.075 s PowerShell/.NET serial read/write | 25.429 sNative files account for about 72% of the bytes but less than 1% of the runtime.
This strongly indicates that the bottleneck is the number of failed copy operations, not disk throughput or total runtime size.
Materializer implementation details
The relevant materializer is in the Electron main-process bundle inside app.asar.
Observed behavior:
- Source:
process.resourcesPath\cua_node - Destination:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\<16-hex-hash> - A staging directory is created first.
- The directory tree is traversed synchronously and serially.
- For every file:
copyFileSync- on the encrypted/Application Protected copy failure:
readFileSyncwriteFileSync
- After completion, staging is renamed to the final runtime directory.
- No full-tree SHA-256 verification is performed.
- Only three identity files are hashed; this takes about 0.13 seconds.
- No download or decompression occurs during this step.
- The synchronous materialization blocks creation of the Renderer.
The runtime hash calculated by this version is:
415ffebf3d576e9b
Steps to reproduce
- Install or update Codex Desktop through Microsoft Store/MSIX on Windows.
- Ensure the new version requires a new
cua_noderuntime hash. - Launch Codex Desktop for the first time after the update.
- Observe that the main process starts but no Renderer appears.
- Monitor:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node - Observe a staging runtime being populated for several minutes.
- After the runtime is complete, the Renderer appears almost immediately.
- A second launch is fast because the runtime is already present.
Expected behavior
Preparing a 318.9 MiB runtime should not block the Codex Desktop UI for several minutes.
Once Codex detects that copyFileSync cannot copy Application Protected / encrypted files from this MSIX source tree, it should avoid repeating the same failing operation for every remaining file.
Suggested minimal fix
The lowest-risk fix appears to be:
- Attempt the normal copy operation.
- On the first known encrypted/Application Protected copy failure (
ERROR_ENCRYPTION_FAILED/ equivalent Node error), switch the remainder of that runtime tree to the existing buffered read/write fallback. - Do not retry the known-failing native copy path for another 4,679 files.
On this machine, simply skipping the repeated failing operations reduces the equivalent serial materialization benchmark from approximately:
430 seconds → 19 seconds
without changing the resulting file contents or runtime structure.
A later optimization could use bounded concurrent read/write operations. An equivalent 32-concurrency benchmark completed in approximately 9 seconds, although a lower concurrency may be preferable for production.
Another useful improvement would be a supported headless prepare-cua-runtime / bootstrap command so runtime preparation does not have to block the first interactive launch.
Additional information
No production Codex runtime, AppX package, app.asar, WindowsApps ACL, Defender configuration, registry entry, or encryption setting was modified during this investigation.
The production runtime remained intact.
Defender may still contribute some portion of the remaining difference between the 429.7-second reproduction and the 485-second real startup, but Defender is not required to explain the primary delay: reproducing Codex's own synchronous fail-then-fallback algorithm already reproduces 88.6% of the observed runtime.
This appears to be closely related to existing Windows MSIX / Application Protected runtime relocation reports, but this report adds a source-level performance root cause and quantitative reproduction showing that repeated failed copy attempts are responsible for most of the first-launch delay.
What steps can reproduce the bug?
-
Install or update Codex Desktop through the Microsoft Store / MSIX package on Windows.
-
Make sure the new Codex version requires a new CUA Node runtime hash under:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node
-
Launch Codex Desktop for the first time after the update.
-
Observe that ChatGPT.exe starts, but no Codex window appears for several minutes.
-
Monitor:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node
A new .staging--... directory is created and populated very slowly.
-
On the affected system, the packaged files under:
\app\resources\cua_node
have the Windows Application Protected / Encrypted attribute.
-
The Electron main-process materializer attempts copyFileSync() for every file.
Each copy attempt fails with the encrypted-copy error path
(Node errno -4094 / code UNKNOWN, consistent with Windows
ERROR_ENCRYPTION_FAILED), then falls back to:readFileSync(source)
writeFileSync(destination) -
This failed copy attempt is repeated independently for all 4,680 files.
-
The runtime takes approximately 485 seconds to materialize.
-
Once the runtime finishes, the Renderer appears about 2 seconds later
and Codex starts normally. -
Close and reopen Codex without updating it.
The second launch is fast because the valid CUA runtime already exists.
What is the expected behavior?
Codex Desktop should not block the first interactive launch for several minutes while preparing a ~319 MiB CUA runtime.
Once the application detects that the normal copy path cannot copy Application Protected / encrypted MSIX files, it should avoid retrying the same known-failing copy operation for every remaining file.
A minimal expected behavior would be:
- Attempt the normal copy operation.
- If the first file fails with the known encrypted/Application Protected copy error, switch the remaining runtime tree to the existing buffered read/write fallback.
- Continue preparing the runtime without repeating thousands of identical failed copy attempts.
- Show the Codex window promptly after runtime preparation completes.
On this machine:
- Current behavior: ~485 seconds
- Exact reproduction of current materializer logic: ~429.7 seconds
- Serial read/write fallback only: ~19.2 seconds
- Bounded parallel read/write: ~9.1 seconds
So the same runtime can be prepared in tens of seconds rather than several minutes without changing its contents or structure.
Ideally, runtime preparation should also either:
- happen asynchronously after the main window is shown, or
- have a supported headless/preparation path so first launch does not appear frozen.
Additional information
Additional diagnostics:
- Codex Desktop version: 26.825.6671.0
- Windows x64, Microsoft Store / MSIX installation
- AppX Stage/Register complete successfully in ~11 seconds total
- The long delay is isolated to CUA runtime materialization
Observed startup timeline:
- Codex main process starts
- New cua_node runtime staging begins ~10 seconds later
- Runtime materialization takes ~485 seconds
- Renderer appears ~2 seconds after materialization completes
- app-server starts ~2 seconds after Renderer
The runtime contains:
- 4,680 files
- 833 subdirectories
- 334,374,010 bytes (318.9 MiB)
Source and materialized runtime have matching file counts, directory counts and total bytes. The runtime identity hash is derived from manifest.json, bin/node.exe and bin/node_repl.exe.
The materializer is implemented in the Electron main-process bundle inside app.asar and performs synchronous, depth-first, serial file processing.
Exact reproduction of the same fail-then-fallback logic completed in ~429.7 seconds, reproducing 88.6% of the real startup delay.
Equivalent copy benchmarks:
- Serial Node read/write: ~19.2 seconds
- PowerShell/.NET serial read/write: ~25.4 seconds
- Bounded parallel Node read/write (32 concurrency): ~9.1 seconds
The bottleneck scales with file count, not data size:
native binaries contain ~72% of the bytes but account for less than 1% of the reproduced materialization time.
No production AppX files, app.asar, WindowsApps ACLs, Defender settings, encryption attributes, or the existing CUA runtime were modified during testing.
Defender may contribute some additional latency, but it is not required to explain the primary issue: reproducing Codex's own synchronous copyFileSync-fail-then-read/write fallback path already reproduces most of the observed delay.
Possibly related issues:
- [Windows] First launch shows no window for about 15 minutes while extracting bundled cua_node runtime #41170
- [Windows][26.825.5331.0] Headless startup caused by Application Protected node_repl.exe relocation failure (0x80071770) #41540
The most important observation is that the fallback itself is fast; the expensive part is retrying a copy operation that is already known to fail on this source tree.
Activity
github-actions commentedon Aug 31, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
haoyxy commentedon Aug 31, 2026
This appears related to #41170, #41539, #41540 and #40843, but this report adds a source-level root cause and quantitative reproduction showing that the repeated per-file copyFileSync failure path accounts for most of the startup delay.
zemeng5208 commentedon Aug 31, 2026
Thanks for the detailed measurements — this is a very strong reproduction of the Windows MSIX/Application Protected path.
Disclosure: I (
zemeng5208) maintain WinBridge Recovery: https://github.com/zemeng5208/winbridge-recoveryFor this specific failure class, WinBridge is relevant only to the local CUA runtime materialization layer. It can help inspect/recover
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node, detect incomplete or stale.staging-*directories, compare the expected/current runtime version/hash state, and distinguish ordinary file-lock/path problems from Application Protected/EFS copy failures. That can be useful when a failed or interrupted materialization leaves the runtime unusable after an update.Your evidence here also defines an important limitation: if the runtime ultimately materializes correctly and the remaining problem is that Codex synchronously retries the same failing
copyFileSync()path thousands of times before falling back to read/write, that is an upstream materializer performance/implementation issue, not something a local recovery tool can permanently fix. WinBridge does not modifyWindowsApps, bypass package protection, or patchapp.asar, and I would not expect it to eliminate the repeated per-file retry behavior itself.So in this report I would use WinBridge mainly to verify that the resulting local CUA runtime is complete/consistent (or recover a partial staging state), while the ~8-minute first-launch regression still needs an upstream change such as remembering the first encrypted-copy failure and switching the rest of the tree directly to the existing buffered fallback.
woniuxiaoshu commentedon Sep 2, 2026
Confirmed that this issue still reproduces on Codex Desktop
26.831.2377.0after a Microsoft Store update from26.825.6671.0.Observed timeline on Windows 11 x64:
in_app_updates_policy_wait_started timeoutMs=300000Launching appAppshot hotkey inactive2c6075088d3180ec, was materialized between 14:30:02 and 14:33:00.The AppX package status, NVMe disk health, Codex state databases, and resulting runtime manifest were all verified as healthy. The packaged CUA runtime source files carry the Windows
Encrypted/ Application Protected attribute.I also inspected the current desktop bundle: the 300-second update-policy timer is a non-blocking fallback and is not the direct source of the delay. The visible delay aligns with synchronous CUA runtime materialization occurring before Renderer creation.
The same protected-file copy failure also affects the bundled plugin marketplace in this build. The desktop logs repeatedly failed while copying
plugins/openai-bundled/plugins/sites/.app.jsonfromWindowsApps, leaving the runtime marketplace stale and preventingcom.openai.codexextensionfrom generating its native-host manifest and registry entry. Both Chrome and Edge extensions remained installed and enabled, but Edge reportedNative transport disconnected.After materializing an unprotected, hash-verified user-space copy of the bundled plugin resources and exposing the already verified CUA Node runtime to the same resource root, Codex successfully:
chrome@openai-bundledversion26.831.21537,com.openai.codexextension.json,extension-host.exeprocesses for both extension IDs.This confirms that the same first-launch regression persists in
26.831.2377.0and can also break browser-extension native transport. Runtime/plugin preparation should either happen outside the interactive startup critical path or switch permanently to the buffered fallback after the first known encrypted-copy failure. At minimum, the application should display a visible preparation/progress state instead of appearing not to launch.tutouhuojianliangzai commentedon Sep 3, 2026
Additional reproduction on 26.901.1978.0: approximately 21 minutes with a running process but no visible window after an update. Adding the newer-version evidence here instead of opening a duplicate, using the Codex App Bug template sections.
What version of the Codex App are you using (From “About Codex” dialog)?
26.901.1978.0, obtained fromGet-AppxPackagerather than the About dialog.Package:
OpenAI.Codex_26.901.1978.0_x64__2p2nqsd0c76g0; package status:Ok. On this installation, the displayed application name and executable are ChatGPT /ChatGPT.exe.What subscription do you have?
ChatGPT Plus.
What platform is your computer?
Windows 11 Pro 25H2, build
26200.9168, x64.The template's PowerShell OS-version check returns
Microsoft Windows NT 10.0.26200.0 x64.The MSIX installation and package-data paths are redirected through junctions to the G: drive; the materialized CUA runtime is on C:. Both volumes are NTFS SSDs with healthy reported status and available space. Microsoft Defender real-time and behavior monitoring were enabled.
What issue are you seeing?
After updating, launching the app leaves a process visible in Task Manager but no usable window for about 21 minutes. It eventually opens without terminating the process or resetting application data.
The measured startup critical path was 1,256,982 ms (20 minutes 57 seconds). AppX registration had already completed successfully before this launch.
Selected log events on 2026-09-03, UTC (unrelated fields and private paths omitted):
The runtime file timestamps overlap almost the entire no-window interval:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\ad3b5049246cde44.manifest.jsoncreation: 10:29:44.408 UTC.The simultaneous late firing of the nominal 5-second and 300-second timeouts is consistent with event-loop blocking, rather than either configured timeout explaining the full delay by itself.
What steps can reproduce the bug?
ChatGPT.exewithout a visible main window.%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_nodeand the desktop startup log.This report documents an observed post-update occurrence, not a deliberately repeated full-tree reproduction. The existing valid runtime was not deleted to force another test.
What is the expected behavior?
The app should display a responsive window and preparation progress promptly. Runtime materialization should not synchronously block the interactive startup path for tens of minutes.
Suggested implementation directions:
Additional information
Current-build implementation and independent copy probe
Read-only inspection of
app.asar, bundle.vite/build/src-BXVxNf6C.js, found the same pattern: cache validation, staging creation, synchronous recursive traversal, per-filecopyFileSync, and areadFileSync/writeFileSyncfallback for recognized errors, followed by staging publication. The build-specific function names werecL,uL, andlL.Sampled packaged source files had
Archive, Encryptedattributes; their materialized counterparts hadArchive.An independent three-file probe wrote only to a workspace scratch directory:
All three ordinary packaged-source copies failed with
code=UNKNOWN,errno=-4094.The probe used the separately installed Node v24.13.1, not the bundled Node v24.19.0. These are small-sample mechanism checks, not a full-tree benchmark or a profiler trace of the original stall. They cannot establish how much of the 21-minute delay came from failed copies, package encryption handling, antivirus inspection, or cross-volume I/O.
Cache validation and investigation limits
The installed and cached
manifest.json,bin/node.exe, andbin/node_repl.exeeach had matching SHA-256 hashes. The computed cache identity matchedad3b5049246cde44, andnode_modulesexisted. This validates the checked identity files, not the contents of all 4,684 files.The combined timestamps, current-build synchronous implementation, and independent copy failures strongly support the same materialization mechanism reported here. Later
EXDEVstate-persistence errors occurred after the window started appearing and are not evidence that those later errors caused the preceding stall.No installed package,
app.asar, production runtime, ACL, encryption attribute, Defender setting, registry entry, or user configuration was modified during this investigation. A subsequent restart and a full-cache prewarming workaround have not been tested.ZLv69 commentedon Sep 3, 2026
Additional Windows reproduction on Codex Desktop
26.831.2377.0after a Microsoft Store/MSIX update.This run strongly correlated the no-window interval with first-run CUA Node runtime materialization.
Observed timeline (relative, private local paths omitted):
ChatGPT.exestarted;%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node;codex.exe ... app-server;Resulting runtime:
bin\node.exe: presentbin\node_repl.exe: presentThe AppX package itself reported
Status = Ok. I did not observe a new failed.staging-*directory for this update; the only staging directory present was an older empty leftover. In other words, this reproduction looks like slow but ultimately successful materialization, rather than the permanently failed staging/EFS variant.A second launch after the runtime had completed was normal, which further supports the first-post-update materialization path as the critical delay on this machine.
I also independently encountered the hidden-window symptom during the stall (
Chrome_WidgetWin_0,Visible=False, no renderer). Forcing that HWND visible early was not a complete fix: synchronousShowWindowcould block until startup progressed, and an internal black Chromium window could become visible. Waiting for runtime preparation to complete was more reliable than repeatedly killing/restarting the app.This is consistent with the core issue here: the interactive UI remains unavailable while runtime preparation is on the startup critical path. A visible preparation/progress state, or moving this work off the Electron main/startup path, would make the update experience much less likely to look like a broken installation.
No production package/runtime contents, ACLs, encryption attributes, registry settings, or authentication data were modified. Local usernames, project paths, and tokens are intentionally omitted.
wenzhiz40 commentedon Sep 4, 2026
Title: [Windows Desktop] UI is blocked until CUA Node runtime staging deployment completes after app updates
Summary
After a Microsoft Store update, the Codex / ChatGPT desktop app launches background processes but does not create a visible window until it finishes deploying a new CUA Node runtime.
The app provides no progress UI, so it appears broken or hung.
Environment
C:\Users\<username>\AppData\Local\OpenAI\Codex\runtimes\cua_nodeSteps to reproduce
ChatGPT.exebackground processes start.MainWindowHandle = 0).C:\Users\<username>\AppData\Local\OpenAI\Codex\runtimes\cua_nodeActual behavior
A new folder such as:
.staging-ad3b5049246cde44-H2m2esis created and gradually filled with thousands of Node runtime files.
During this time:
ChatGPT.exeuses roughly one CPU core continuously.Example from version 26.901.1978.0:
Expected behavior
The desktop window should appear promptly after launch.
If CUA runtime deployment is required, it should either:
The application should not look like a silent renderer startup failure while this work is running.
Impact
This has repeatedly led to unnecessary repair/reset/reinstall attempts because the app only appears as background processes with no visible indication that runtime deployment is still in progress.
18701035286lx-afk commentedon Sep 6, 2026
Additional confirmation: the post-update startup delay still occurs on ChatGPT/Codex Desktop 26.901.6511.0.
Environment:
OpenAI.Codex_26.901.6511.0Encryptedattribute.Local desktop logs show the same pattern across four consecutive updates:
Subsequent launches of the earlier versions generally took approximately 3–9 seconds.
For the September 6 launch, local timestamps (UTC+8) show:
ChatGPT.exeprocess created.cua_noderuntime.The runtime contains 4,684 files, approximately 322 MiB, under:
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\b474a88d5d105afaRead-only inspection of the installed bundle confirms that runtime relocation still uses synchronous recursive copying, with
copyFileSyncfollowed by areadFileSync/writeFileSyncfallback for the recognized copy errors.A particularly useful log symptom is that the shell-environment timeout configured for 5,000 ms was only reported after 432,992 ms. Its callback and the update-policy timeout were both logged immediately after the long startup gap, consistent with main-thread blocking.
After startup completed, validation confirmed:
manifest.json,bin/node.exe, andbin/node_repl.exe.This closely matches the runtime-materialization issue described here. I have not independently benchmarked the failed native-copy attempts on this machine, so their individual contribution remains unmeasured. A second launch of the current version has also not yet been tested.
The investigation was read-only. No package files, runtime cache, application configuration, permissions, or security settings were changed.
Please keep this report applicable to the newer
26.901.6511.0build. Detecting the encrypted-copy failure once per source tree and moving runtime preparation off the main thread would address the behavior observed here.xin115 commentedon Sep 15, 2026
Still reproducible on Windows x64 MSIX packages 26.908.4834.0 and 26.908.9136.0 (2026-09-15). Adding sanitized measurements and suggested fixes. The reporting user explicitly authorized publishing these diagnostics and recommendations here.
Observed startup
In 26.908.9136.0, launch-to-primary-window readiness took approximately 213 seconds. Runtime directory creation/population occupied approximately 206.5 seconds. The window itself reported
startupElapsedMs=1383once its initialization started. Runtime resolution reportedsource=copied,coreFrameworkActive=false.The preceding version, 26.908.4834.0, also took approximately 216 seconds to reach window readiness. Its new runtime contained 4,123 files / 251.2 MiB, with file creation spanning approximately 207 seconds.
Bounded reproduction
A separate Node process copied 80 sampled runtime files smaller than 128 KiB (408,755 bytes total) into temporary workspace directories:
copyFileSync, followed by buffered read/write on failureUNKNOWN,errno=-4094; all fallback copies succeededcopyFileSyncon the same filesreadFileSync+writeFileSyncThe roughly 50 ms extra cost per file extrapolates to approximately 206 seconds for 4,123 files, closely matching observed deployment time. This is a sample-based inference, not a full-tree trace. Trials were sequential and cache effects were not controlled; the direct read/write trial additionally included comparison reads.
Read-only inspection of the installed bundle confirms synchronous recursive copying: every file independently attempts
copyFileSync, catches the recognized error, and falls back to buffered read/write. Failure is not remembered for the source tree.A startup shell-environment timeout reported
timeoutMs=5000butdurationMs=212041, consistent with synchronous startup work delaying timer delivery; this alone is not evidence of a 212-second shell invocation.Suggested fixes
UNKNOWNerror as encryption failure.Healthy NVMe SSDs were reported locally, but this does not exclude all storage/security-software overhead. No installed application code, runtime cache, WindowsApps permissions, Defender settings, or user configuration was modified. Temporary benchmark copies were removed. No credentials, personal paths, or conversation transcript are included.
helo060228 commentedon Sep 20, 2026
Additional confirmation on a different runtime version.
Environment:
OpenAI.Codex26.915.4065.0df473e5367fa2b42The first launch after the update stayed headless for about 26 minutes before the window appeared. The runtime directory that launch left behind matches the expected materialization output:
So the materialization window on this machine is about 25.5 minutes, which lines up with the observed first launch.
No
.staging-*directory was left behind, so I cannot add per-file timings, but the per-file cost here (~0.68 s) is noticeably higher than in your reproduction (~0.10 s), which may point at a second factor on this machine.