[Windows 26.820] Codex Desktop cannot start: bundled codex.exe relocation from WindowsApps fails

Open 💬 36 comments Opened Aug 25, 2026 by bevis7781
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

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

26.820.7780.0 (from Get-AppxPackage; the app cannot start to open the About Codex dialog)

What subscription do you have?

ChatGPT Plus

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

After updating Codex Desktop to version 26.820.7780.0, the app can no longer start.

The startup dialog reports:

Unable to locate the Codex CLI binary.
Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

However, the bundled Windows CLI is present at:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0\app\resources\codex.exe

The startup logs show that the actual failure occurs earlier, while Codex attempts to relocate the bundled Windows executable from the WindowsApps package into the per-user runtime directory.

Relevant log fields:

bundled_executable_relocation_failed
operation=copy_file
executableName=codex.exe
failedExecutableName=codex.exe
sourceKind=windowsapps

sourcePath:
C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0\app\resources\codex.exe

destinationPath:
C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\.staging-...\codex.exe

originalError:
errno=-4094
code=UNKNOWN
syscall=copyfile

Immediately afterwards, AppServerConnection fails with:

Unable to locate the Codex CLI binary.

The bundled files:

app\resources\codex.exe
app\resources\codex

both report the Windows file attributes:

Archive, Encrypted

A manual copy test of the bundled codex file from WindowsApps to a normal temporary directory also fails with:

The specified file could not be encrypted.

During the same startup sequence, Codex also fails to relocate the bundled cua_node runtime using copy_directory.

The app worked before the update and stopped starting immediately after updating to 26.820.7780.0.

What steps can reproduce the bug?

  1. Update/install Codex Desktop from the Microsoft Store to version 26.820.7780.0 on this Windows x64 machine.
  1. Launch Codex Desktop.
  1. The app attempts to relocate the bundled codex.exe from the WindowsApps package into:

%LOCALAPPDATA%\OpenAI\Codex\bin\

  1. The relocation fails during copy_file.
  1. Codex then displays:

"Unable to locate the Codex CLI binary."

Potentially relevant AppX environment details:

Get-AppxDefaultVolume reports:

D:\WindowsApps

Get-AppxPackage OpenAI.Codex reports:

Version:
26.820.7780.0

InstallLocation:
C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

A directory for the same Codex package/version is visible under both:

C:\Program Files\WindowsApps\
D:\WindowsApps\

I have not modified WindowsApps permissions, ownership, ACLs, package files, encryption settings, Codex configuration, or CODEX_CLI_PATH.

What is the expected behavior?

Codex Desktop should successfully locate or relocate the bundled Windows Codex CLI and start normally.

If WindowsApps / Application Protected / encrypted package resources cannot be copied to the per-user runtime directory using the current copy mechanism, Codex should use a Windows-compatible relocation method and surface the underlying Windows error instead of reporting that the CLI is missing.

Additional information

This appears related to existing Windows bundled-runtime relocation issues, but the impact in this case is more severe: the Windows-native codex.exe relocation failure prevents the entire Codex Desktop app from starting.

Potentially related issues:

#25571 - WindowsApps package on a non-system AppX volume / protected bundled executable relocation failures
#38696 - encrypted bundled Codex relocation failure in the WSL path
#34764 - Application Protected cua_node relocation failure

The same startup sequence on this machine shows both codex.exe copy_file relocation failures and cua_node copy_directory relocation failures.

The "Check for Updates" button in the startup error dialog still works and currently reports:

ChatGPT is up to date.

No workaround or local modification has been applied after reproducing the issue, so the failing installation state is currently preserved.

View original on GitHub ↗

36 Comments

ahku667 · 2 days ago

I can independently reproduce this on the exact same Windows package:

  • OpenAI.Codex 26.820.7780.0 x64
  • Windows 11 10.0.26200.0
  • ChatGPT Plus

Important: my Desktop configuration is Windows-native:

runCodexInWindowsSubsystemForLinux = false
integratedTerminalShell = "powershell"

The bundled binaries are present:

app\resources\codex.exe = exists
app\resources\codex     = exists

Both report:

Attributes: Archive, Encrypted

A direct copy reproduction of the packaged Linux codex binary to %TEMP% fails with:

COPY_RESULT=FAILED
ERROR=The specified file could not be encrypted.
HRESULT=80071770

The Desktop startup log shows the same Windows-native relocation failure:

bundled_executable_relocation_failed
operation=copy_file
executableName=codex.exe
failedExecutableName=codex.exe
sourceKind=windowsapps

sourcePath:
C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0\app\resources\codex.exe

destinationPath:
C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\.staging-...\codex.exe

Immediately afterwards:

Unable to locate the Codex CLI binary.

The same startup sequence also contains relocation failures for the bundled cua_node / Node runtime using copy_directory.

Windows Settings > Apps > ChatGPT > Repair did not resolve the issue.

I did not modify WindowsApps ownership, ACLs, package files, encryption, CODEX_CLI_PATH, the bundled binaries, or Codex runtime state before reproducing this.

Additional AppX-volume evidence from a final read-only audit:

REGISTERED_INSTALL_LOCATION=
C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

DEFAULT_APPX_VOLUME=
F:\WindowsApps

An exact package directory for the same package full name also exists at:

F:\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

The C: and F: copies of both bundled binaries are byte-identical by size and SHA-256:

codex.exe
size = 307,568,432 bytes
sha256 = 09D6723925E724EDF0BBBBC7B9E204526E0FB1462C86BD2A4997311FD5071EBA
attributes = Archive, Encrypted

codex
size = 265,274,528 bytes
sha256 = EC77CF443344309A29859E16204CAC6F0BAE162FFD39427E94F24AEEBB5E3D68
attributes = Archive, Encrypted

The hashes are identical on C: and F:.

So this machine has a multi-AppX-volume mismatch/state in which the default AppX volume is F:, the registered Codex package install location is C:, and an identical copy of the same package/version is also present under F:\WindowsApps.

I cannot prove that this multi-volume state is the root cause rather than only a trigger/amplifier, but it closely matches the potentially relevant environment shape already described in #40700.

This appears to confirm that #40700 affects the Windows-native path itself, not only the WSL agent path, and that the underlying failure is consistent with ERROR_ENCRYPTION_FAILED (0x80071770) / protected MSIX resource relocation.

hz3204323 · 2 days ago

I can reproduce this exact regression on Windows x64.

Working: 26.818.8289.0
Broken: 26.820.7780.0

Additional evidence from my machine:

  • app\resources\codex.exe and app\resources\codex both exist in the 26.820.7780.0 package.
  • Both report Windows file attributes Archive, Encrypted / Application Protected behavior.
  • The earliest native startup failure is:
  • bundled_executable_relocation_failed
  • executableName=codex.exe
  • platform=win32
  • operation=copy_file
  • source: ...\WindowsApps\OpenAI.Codex_26.820.7780.0...\app\resources\codex.exe
  • destination: %LOCALAPPDATA%\OpenAI\Codex\bin\.staging-...\codex.exe
  • errno=-4094, code=UNKNOWN
  • Only after that does the UI report Unable to locate the Codex CLI binary.
  • A manual Copy-Item of the bundled codex file from WindowsApps to %TEMP% fails with: The specified file could not be encrypted.

This is the Windows-native CLI path in my failing log, not the WSL bootstrap path. CODEX_CLI_PATH is unset, and the runCodexInWindowsSubsystemForLinux setting is not present in my config.

My %USERPROFILE%\.codex is a Junction to D:\ChatGPT\CodexHome, but that same Junction/D-drive layout was present while 26.818.8289.0 worked normally, so it does not explain the version-specific regression.

I also compared the two desktop builds: 26.818.8289.0 can directly resolve/run the bundled resources\codex.exe, while 26.820.7780.0 routes startup through the relocation helper first. The old build also logged some bundled-runtime/plugin copy warnings, but they were non-fatal; the new build appears to make successful native codex.exe relocation a prerequisite for startup.

I downloaded the official previous release MSIX from OpenAI's CDN and downgraded with:

Add-AppxPackage "$HOME\Downloads\ChatGPT-x64.msix" -ForceUpdateFromAnyVersion

After returning to 26.818.8289.0, the desktop app started immediately and my existing projects, sessions, and configuration were still intact.

This looks like a regression in the new mandatory Windows-native CLI relocation path when the source resource is Store/MSIX Application Protected.

xianlitijun · 2 days ago

Independent reproduction of this release regression on Windows 11:

  • ChatGPT/Codex Desktop was working normally before today's (2026-08-25) Windows app update.
  • Immediately after updating to the latest release, the app fails on first launch with the same fatal dialog:

ChatGPT failed to start.

Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

  • This machine had not encountered the issue on prior builds; the failure began only after today's update.
  • The main app is now completely inaccessible, so this is a blocking startup regression rather than a feature-level failure.
  • The startup dialog still exposes Check for Updates, but the current release is already the latest.

This appears consistent with #40700 and adds another update-triggered reproduction. A screenshot of the exact dialog is available if maintainers need it.

zemeng5208 · 2 days ago

I maintain WinBridge Recovery: https://github.com/zemeng5208/winbridge-recovery

This report is a high-confidence match for one of the local Windows layers WinBridge is designed to diagnose: bundled executable/runtime relocation from the installed MSIX/WindowsApps package into the per-user Codex runtime, including Application Protected/EFS copy failures and incomplete staging.

For this specific failure, the useful local checks are:

  • verify that the packaged app\resources\codex.exe / codex and cua_node sources exist and are readable;
  • inspect their Windows encryption/Application Protected state;
  • inspect %LOCALAPPDATA%\OpenAI\Codex\bin and runtimes\cua_node for abandoned .staging-* directories or an incomplete active runtime;
  • compare any existing per-user runtime files against the currently installed package by size/hash before deciding whether local state is reusable;
  • distinguish a destination-path/Junction problem from the ERROR_ENCRYPTION_FAILED copy path shown here.

WinBridge can help collect that evidence and recover user-side staging/runtime state where a valid current-package copy can be materialized safely. It does not modify WindowsApps, bypass package protection, or guarantee a fix. In particular, if Desktop 26.820.7780.0 now requires codex.exe to be copied with a mechanism that does not allow an Application Protected source to an unencrypted destination, then the durable fix is upstream in Codex's Windows relocation implementation (for example, using a decrypted-destination-compatible copy path and reusing a verified existing runtime when appropriate).

CanLoop16 · 2 days ago

Same issue!!!

Run the following command in Windows Powershell and i get the correct respond:

> Get-AppxPackage *Codex* | Select-Object Name, PackageFullName, Version, InstallLocation

Name         PackageFullName                               Version       InstallLocation
OpenAI.Codex OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0 26.820.7780.0 C:\Program Files\WindowsApps\OpenAI.Codex_2...

But run where.exe codex i can't find anything.

eksynn · 2 days ago

I can reproduce this exactly on Windows x64 with OpenAI.Codex 26.820.7780.0.

The app worked normally before the update. Immediately after updating to 26.820.7780.0, startup failed with:

Unable to locate the Codex CLI binary.

My AppX configuration is:

Get-AppxDefaultVolume
PackageStorePath: B:\WindowsApps
IsSystemVolume: False

while the affected package was registered at:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

I rolled back to the official 26.818.8289.0 MSIX using:

Add-AppxPackage -Path "B:\ChatGPT-Rollback\ChatGPT-26.818.8289.0-x64.msix" -ForceUpdateFromAnyVersion -ForceApplicationShutdown

and ChatGPT immediately launches normally again.

Please also make the updater preserve the user's configured/existing AppX installation volume. My Windows default app volume is explicitly B:\WindowsApps; the ChatGPT package should not silently fall back to or migrate onto C: during installation or updates.

If relocation of bundled runtime files is necessary, it should work correctly with a non-system AppX volume rather than requiring the application itself to live on C:.

pwnfan · 2 days ago

I reproduced the same 26.820.7780.0 startup regression on another Windows x64 machine and recovered the app without rolling back, changing WindowsApps permissions or ownership, or setting CODEX_CLI_PATH.

✅ Start here: verified no-rollback recovery

This is not only a bug report. A working recovery is included in this comment and was validated on OpenAI.Codex 26.820.7780.0 x64. It restored normal desktop startup and both the Windows-native and WSL app servers without rolling back, modifying WindowsApps ACLs/ownership, or setting CODEX_CLI_PATH.

Comment permalink (copy this URL):

https://github.com/openai/codex/issues/40700#issuecomment-5419391502

Fastest option when the desktop app cannot start: give the permalink above to a Codex agent that still runs and can access the Windows host filesystem, for example:

  • Codex CLI on Windows, even when the ChatGPT desktop app cannot start;
  • Codex CLI inside WSL;
  • a ChatGPT desktop session running inside WSL, or another Codex session that can access the Windows host paths.

You can send the agent this prompt:

Read this GitHub comment. First perform read-only checks of my installed ChatGPT/Codex desktop version, WindowsApps resource attributes, and latest startup log. Confirm that this is the same ERROR_ENCRYPTION_FAILED / bundled_executable_relocation_failed failure. Only if it matches, use the currently installed official package to materialize and verify the per-user caches described in the comment, then relaunch and validate startup. Do not change WindowsApps ACLs, ownership, package files, or my Codex configuration, and do not set CODEX_CLI_PATH.

The agent can adapt the paths to the actual installation and let the user review the commands before execution. Do not put account credentials, tokens, or other secrets in the GitHub comment or prompt.

If you prefer to perform the recovery manually, go directly to Manual recovery (PowerShell) below. The script dynamically computes the five version-directory IDs from the currently installed package. It has been validated on 26.820.7780.0 x64 and stops before writing if the known bundle layout is not present.

Root cause confirmation

The first failure is not the WSL environment failing to find a user-installed Codex CLI. The desktop app cannot copy resources carrying the Encrypted / Application Protected attribute from the MSIX package into its per-user cache:

bundled_executable_relocation_failed
operation=copy_file
executableName=codex.exe
sourceKind=windowsapps
originalError: The specified file could not be encrypted.
HRESULT: 0x80071770 / ERROR_ENCRYPTION_FAILED

Only afterward does it emit the misleading secondary errors:

Unable to locate the Codex CLI binary.
Desktop bootstrap failed to start the main app.

The same launch also fails while copying the cua_node directory and rg.exe. Therefore, restoring only the WSL codex file, setting CODEX_CLI_PATH, or reinstalling the same MSIX package is insufficient for this Windows-native bootstrap regression.

Version-directory rule used by the app

The app does not use a fixed bin/codex path. It derives a 16-character directory name from a resource descriptor. In the app-defined file order, each entry contributes:

<UTF-8 file name> NUL <lowercase SHA-256 hex digest of that file> NUL

The app hashes the complete descriptor with SHA-256 and uses its first 16 characters.

For the official 26.820.7780.0 x64 package, the resulting IDs are:

Windows CLI   d0097be4feba73d0
cua_node      950613ca46815e82
Windows rg    b91d382ea836415f
WSL CLI       bf0dd1e87d338bce
WSL rg        1a4f6f66dd2f3710

The Windows CLI descriptor contains, in order:

codex.exe
codex-code-mode-host.exe
codex-windows-sandbox-setup.exe
codex-command-runner.exe

The cua_node descriptor contains:

manifest.json
bin/node.exe
bin/node_repl.exe

The WSL CLI descriptor contains:

codex
codex-code-mode-host

Manual recovery (PowerShell)

The PowerShell script below selects the currently installed official OpenAI.Codex x64 package and dynamically computes all five version-directory IDs from its resource bytes. The same script can therefore be rerun after a future update when the bundle file lists, ordering, hashing algorithm, and cache layout remain unchanged. If a known bundle file is absent, it stops before writing. It reads package resources with FileStream and creates ordinary destination files so the destination does not inherit the source's Application Protected/EFS state. It writes into a random staging directory, verifies file size and SHA-256, and then renames the staging directory atomically.

Safety boundaries:

  • It does not modify any WindowsApps file, ACL, ownership, or encryption setting.
  • It does not modify Codex configuration, sessions, or CODEX_CLI_PATH.
  • It computes directory IDs from the current package and fails closed if the known bundle layout has changed.
  • It does not overwrite an existing mismatched version directory; it stops on a conflict.
  • It only materializes user-writable caches from the currently installed official package and does not redistribute OpenAI binaries.
  • Fully quit ChatGPT/Codex first. Copying the 4,018 cua_node files may take several minutes.

<details>
<summary>PowerShell recovery script (dynamic bundle IDs; known x64 package layout)</summary>

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

if (Get-Process ChatGPT, Codex -ErrorAction SilentlyContinue) {
    throw "Please fully quit ChatGPT/Codex before running this script."
}

$pkg = Get-AppxPackage OpenAI.Codex |
    Sort-Object Version -Descending |
    Select-Object -First 1

if ($null -eq $pkg) {
    throw "OpenAI.Codex is not installed."
}
if ($pkg.PackageFullName -notmatch "_x64__") {
    throw "This script is only validated for the known x64 package layout: $($pkg.PackageFullName)."
}

$resources = Join-Path $pkg.InstallLocation "app\resources"
$localRoot = Join-Path $env:LOCALAPPDATA "OpenAI\Codex"
$wslRoot = Join-Path $env:USERPROFILE ".codex\bin\wsl"

function Get-Sha256Hex([string]$Path) {
    $stream = [IO.File]::Open(
        $Path,
        [IO.FileMode]::Open,
        [IO.FileAccess]::Read,
        [IO.FileShare]::Read
    )
    $sha = [Security.Cryptography.SHA256]::Create()
    try {
        return ([BitConverter]::ToString($sha.ComputeHash($stream))).Replace("-", "").ToLowerInvariant()
    }
    finally {
        $sha.Dispose()
        $stream.Dispose()
    }
}

function Get-BundleId([string]$SourceRoot, [string[]]$LogicalNames) {
    $descriptor = [Text.StringBuilder]::new()
    foreach ($logicalName in $LogicalNames) {
        $physicalName = $logicalName.Replace([char]'/', [IO.Path]::DirectorySeparatorChar)
        $sourcePath = Join-Path $SourceRoot $physicalName
        if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
            throw "Unsupported bundle layout; missing file: $sourcePath"
        }
        [void]$descriptor.Append($logicalName)
        [void]$descriptor.Append([char]0)
        [void]$descriptor.Append((Get-Sha256Hex $sourcePath))
        [void]$descriptor.Append([char]0)
    }

    $sha = [Security.Cryptography.SHA256]::Create()
    try {
        $bytes = [Text.Encoding]::UTF8.GetBytes($descriptor.ToString())
        return ([BitConverter]::ToString($sha.ComputeHash($bytes))).Replace("-", "").ToLowerInvariant().Substring(0, 16)
    }
    finally {
        $sha.Dispose()
    }
}

$ids = @{
    WindowsCli = Get-BundleId $resources @(
        "codex.exe",
        "codex-code-mode-host.exe",
        "codex-windows-sandbox-setup.exe",
        "codex-command-runner.exe"
    )
    CuaNode = Get-BundleId (Join-Path $resources "cua_node") @(
        "manifest.json",
        "bin/node.exe",
        "bin/node_repl.exe"
    )
    WindowsRg = Get-BundleId $resources @("rg.exe")
    WslCli = Get-BundleId $resources @("codex", "codex-code-mode-host")
    WslRg = Get-BundleId $resources @("rg")
}

function Assert-SameFile([string]$Source, [string]$Destination) {
    if (-not (Test-Path -LiteralPath $Destination -PathType Leaf)) {
        throw "Missing destination file: $Destination"
    }
    if ((Get-Item -LiteralPath $Source).Length -ne (Get-Item -LiteralPath $Destination).Length) {
        throw "File size mismatch: $Destination"
    }
    if ((Get-Sha256Hex $Source) -ne (Get-Sha256Hex $Destination)) {
        throw "SHA-256 mismatch: $Destination"
    }
}

function Copy-PlainFile([string]$Source, [string]$Destination) {
    [IO.Directory]::CreateDirectory((Split-Path -Parent $Destination)) | Out-Null
    $inputStream = [IO.File]::Open(
        $Source,
        [IO.FileMode]::Open,
        [IO.FileAccess]::Read,
        [IO.FileShare]::Read
    )
    $outputStream = [IO.File]::Open(
        $Destination,
        [IO.FileMode]::CreateNew,
        [IO.FileAccess]::Write,
        [IO.FileShare]::None
    )
    try {
        $inputStream.CopyTo($outputStream)
    }
    finally {
        $outputStream.Dispose()
        $inputStream.Dispose()
    }
}

function Publish-FileBundle(
    [string]$SourceRoot,
    [string]$DestinationRoot,
    [string]$Id,
    [string[]]$Files
) {
    [IO.Directory]::CreateDirectory($DestinationRoot) | Out-Null
    $final = Join-Path $DestinationRoot $Id

    if (Test-Path -LiteralPath $final) {
        foreach ($relative in $Files) {
            Assert-SameFile (Join-Path $SourceRoot $relative) (Join-Path $final $relative)
        }
        return $final
    }

    $stage = Join-Path $DestinationRoot (".repair-{0}-{1}" -f $Id, [guid]::NewGuid().ToString("N"))
    [IO.Directory]::CreateDirectory($stage) | Out-Null
    try {
        foreach ($relative in $Files) {
            Copy-PlainFile (Join-Path $SourceRoot $relative) (Join-Path $stage $relative)
        }
        foreach ($relative in $Files) {
            Assert-SameFile (Join-Path $SourceRoot $relative) (Join-Path $stage $relative)
        }
        Move-Item -LiteralPath $stage -Destination $final
    }
    catch {
        if (Test-Path -LiteralPath $stage) {
            Remove-Item -LiteralPath $stage -Recurse -Force
        }
        throw
    }
    return $final
}

function Publish-DirectoryBundle(
    [string]$SourceRoot,
    [string]$DestinationRoot,
    [string]$Id,
    [string[]]$DescriptorFiles
) {
    [IO.Directory]::CreateDirectory($DestinationRoot) | Out-Null
    $sourceRoot = $SourceRoot.TrimEnd("\")
    $final = Join-Path $DestinationRoot $Id

    if (Test-Path -LiteralPath $final) {
        foreach ($relative in $DescriptorFiles) {
            Assert-SameFile (Join-Path $sourceRoot $relative) (Join-Path $final $relative)
        }
        $sourceCount = @(Get-ChildItem -LiteralPath $sourceRoot -File -Recurse -Force).Count
        $finalCount = @(Get-ChildItem -LiteralPath $final -File -Recurse -Force).Count
        if ($sourceCount -ne $finalCount) {
            throw "Runtime file-count mismatch: source=$sourceCount destination=$finalCount"
        }
        return $final
    }

    $stage = Join-Path $DestinationRoot (".repair-{0}-{1}" -f $Id, [guid]::NewGuid().ToString("N"))
    [IO.Directory]::CreateDirectory($stage) | Out-Null
    try {
        Get-ChildItem -LiteralPath $sourceRoot -Directory -Recurse -Force | ForEach-Object {
            $relative = $_.FullName.Substring($sourceRoot.Length).TrimStart("\")
            [IO.Directory]::CreateDirectory((Join-Path $stage $relative)) | Out-Null
        }
        Get-ChildItem -LiteralPath $sourceRoot -File -Recurse -Force | ForEach-Object {
            $relative = $_.FullName.Substring($sourceRoot.Length).TrimStart("\")
            Copy-PlainFile $_.FullName (Join-Path $stage $relative)
        }

        foreach ($relative in $DescriptorFiles) {
            Assert-SameFile (Join-Path $sourceRoot $relative) (Join-Path $stage $relative)
        }
        $sourceCount = @(Get-ChildItem -LiteralPath $sourceRoot -File -Recurse -Force).Count
        $stageCount = @(Get-ChildItem -LiteralPath $stage -File -Recurse -Force).Count
        if ($sourceCount -ne $stageCount) {
            throw "Runtime file-count mismatch: source=$sourceCount staging=$stageCount"
        }
        Move-Item -LiteralPath $stage -Destination $final
    }
    catch {
        if (Test-Path -LiteralPath $stage) {
            Remove-Item -LiteralPath $stage -Recurse -Force
        }
        throw
    }
    return $final
}

$windowsCli = Publish-FileBundle `
    $resources `
    (Join-Path $localRoot "bin") `
    $ids.WindowsCli `
    @(
        "codex.exe",
        "codex-code-mode-host.exe",
        "codex-windows-sandbox-setup.exe",
        "codex-command-runner.exe"
    )

$cuaNode = Publish-DirectoryBundle `
    (Join-Path $resources "cua_node") `
    (Join-Path $localRoot "runtimes\cua_node") `
    $ids.CuaNode `
    @("manifest.json", "bin/node.exe", "bin/node_repl.exe")

$windowsRg = Publish-FileBundle `
    $resources `
    (Join-Path $localRoot "bin") `
    $ids.WindowsRg `
    @("rg.exe")

$wslCli = Publish-FileBundle `
    $resources `
    $wslRoot `
    $ids.WslCli `
    @("codex", "codex-code-mode-host")

$wslRg = Publish-FileBundle `
    $resources `
    $wslRoot `
    $ids.WslRg `
    @("rg")

& (Join-Path $windowsCli "codex.exe") --version
& (Join-Path $cuaNode "bin\node.exe") --version
& (Join-Path $windowsRg "rg.exe") --version | Select-Object -First 1

[pscustomobject]@{
    PackageVersion = $pkg.Version.ToString()
    WindowsCli = $windowsCli
    CuaNode    = $cuaNode
    WindowsRg  = $windowsRg
    WslCli     = $wslCli
    WslRg      = $wslRg
} | Format-List

Write-Host "Recovery materialization completed for OpenAI.Codex $($pkg.Version). Start ChatGPT/Codex normally."

</details>

Validation from the recovered machine

Before recovery, the launch probe consistently reported:

Verdict: RED
Signals: BOOTSTRAP_FAILED, CLI_NOT_FOUND, RELOCATION_FAILED

After materializing the five version directories from the currently installed official package:

codex-cli 0.150.0-alpha.8
node v24.19.0
ripgrep 15.2.0
cua_node source files: 4018
cua_node cached files: 4018

The key bundle files matched the package sources by size and SHA-256. After relaunch:

hostId=local initialized=true next=connected
hostId=remote-ssh-codex-managed:WSL-Ubuntu initialized=true next=connected

The new launch logs no longer contained:

bundled_executable_relocation_failed
Unable to locate the Codex CLI binary
Desktop bootstrap failed
fatal_error_broadcasted

The desktop UI was also confirmed to launch normally.

Suggested upstream fix

Please make WindowsApps resource relocation support an Application Protected/EFS source and an ordinary decrypted per-user destination, for example by:

  • using a Windows copy path equivalent to COPY_FILE_ALLOW_DECRYPTED_DESTINATION; or
  • falling back to buffered read/write when the current copyFile receives ERROR_ENCRYPTION_FAILED;
  • preserving the existing staging, SHA-256 validation, and atomic rename behavior;
  • surfacing the underlying Win32 error instead of reporting every such failure as "CLI binary missing."

This remains a bundle-layout-specific temporary recovery. The script now recomputes the directory IDs from the installed package, so it can be rerun unchanged when an update changes only the version and resource bytes. It deliberately stops if the known file lists are no longer present. The durable fix belongs in the app's relocation implementation.

Related: #38696, #34764, #25571.

981434631 · 2 days ago

I can independently reproduce this exact startup regression on another Windows x64 machine.

Environment

  • OpenAI.Codex: 26.820.7780.0
  • Windows: 10.0.26200.0 x64
  • Package status: Ok
  • Registered install location: C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0
  • Default AppX volume: F:\WindowsApps

The packaged CLI exists at app\resources\codex.exe, but launching the desktop app fails with:

ChatGPT failed to start.
Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

On this machine:

  • the packaged codex.exe has attributes Archive, Encrypted;
  • a working copy under %LOCALAPPDATA%\OpenAI\Codex\bin\codex.exe has attributes Archive;
  • the packaged and user-directory copies are byte-identical by SHA-256:

09D6723925E724EDF0BBBBC7B9E204526E0FB1462C86BD2A4997311FD5071EBA;

  • the copied CLI reports codex-cli 0.150.0-alpha.8.

Reproduction / workaround confirmation

  1. With the user-level CODEX_CLI_PATH unset, relaunching immediately reproduces the fatal startup dialog.
  2. Copying the current package's four Windows CLI executables (codex.exe, codex-code-mode-host.exe, codex-windows-sandbox-setup.exe, and codex-command-runner.exe) into %LOCALAPPDATA%\OpenAI\Codex\bin\ succeeds when materialized as ordinary files.
  3. Setting the user-level variable to %LOCALAPPDATA%\OpenAI\Codex\bin\codex.exe allows Codex Desktop to start, and the running codex.exe process is the user-directory copy.

This strongly supports the existing diagnosis: the bundled executable is present and valid, but the automatic WindowsApps-to-per-user relocation/materialization path fails. The generic “CLI binary missing” dialog is a downstream symptom.

The environment-variable workaround restores the current release, but it bypasses automatic CLI discovery/relocation and can pin the desktop app to this copied CLI after a future update. Please fix the Windows relocation path (including encrypted/Application Protected package resources and cross-AppX-volume states), and surface the underlying copy error in the startup dialog.

xiaodeng2025 · 2 days ago

I can independently reproduce this on Codex App 26.820.7780.0 / Windows 10.0.26200.0 x64.
The bundled codex.exe exists, is marked Encrypted, and executing it directly returns Access is denied.
The issue appeared immediately after updating. My duplicate report was #40762.

Daozhu1007 · 2 days ago

Adding a few data points from my machine (26.820.7780.0, Windows 11 10.0.26200 x64) that may help triage:

1. This relocation step has been flaky since at least Aug 18 — the update just made it fatal.

My desktop logs show bundled_executable_relocation_failed (same errno=-4094 / UNKNOWN / copyfile) intermittently on Aug 18, 22, 23, 24 and 25, while the app still started fine — the previously relocated binary in %LOCALAPPDATA%\OpenAI\Codex\bin was still present, so the failed relocation only logged a warning. After updating to 26.820.7780.0 the app no longer accepted the old binary and attempted a fresh relocation, which failed, leaving no binary at all. There seems to be no fallback when bin\codex.exe is missing.

2. CopyFileW hangs on the packaged binaries; a plain read/write stream copy works.

app\resources\codex.exe shows the Archive, Encrypted attributes here too (confirming @xiaodeng2025's observation). One caveat: the successfully-relocated April-era binary also carries Archive, Encrypted, so the attribute alone doesn't explain why relocation used to succeed. But the CopyFileW behavior is clearly broken: the app's fs.copyFile fails with -4094, and PowerShell Copy-Item on an 8 MB packaged exe hangs indefinitely (>90 s, never completes). A stream copy that doesn't go through CopyFileW ([IO.File]::OpenRead + CopyTo, or cp in Git Bash) completes in under a second and produces a hash-identical, working binary with the Encrypted attribute cleared.

So a possible app-side fix: when the copyfile relocation fails, fall back to a read/write stream copy — that would make relocation robust regardless of the underlying cause.

3. Verified recovery (no rollback, no permission changes):

$src = Join-Path (Get-AppxPackage OpenAI.Codex).InstallLocation 'app\resources'
$dst = "$env:LOCALAPPDATA\OpenAI\Codex\bin"
New-Item -ItemType Directory -Force -Path $dst | Out-Null
'codex.exe','codex-code-mode-host.exe','codex-command-runner.exe','codex-windows-sandbox-setup.exe','rg.exe' | ForEach-Object {
  $in = [IO.File]::OpenRead("$src\$_"); $out = [IO.File]::Create("$dst\$_"); $in.CopyTo($out); \$in.Close(); $out.Close()
}
[Environment]::SetEnvironmentVariable('CODEX_CLI_PATH', "$dst\codex.exe", 'User')

After this the app starts normally: zero fatal errors in the desktop log, app_server_connection reaches connected/initialized=true, and the running codex.exe is confirmed to be the manually placed copy.

liangjxiong · 2 days ago

Another exact reproduction on OpenAI.Codex 26.820.7780.0 x64.

Environment/audit:

  • Registered install location: C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0...
  • No separate ChatGPT AppX package is returned by Get-AppxPackage *ChatGPT*.
  • Persistent CODEX_CLI_PATH is unset at both User and Machine scopes.
  • ~/.codex/config.toml contains no runCodexInWindowsSubsystemForLinux, integratedTerminalShell, CODEX_CLI_PATH, or sandbox-bin override.

There had previously been a process-local workaround value pointing at %USERPROFILE%\.codex\.sandbox-bin\codex.exe; removing it clears the environment variable. That workaround could allow the desktop app to get further/start, but then Codex was unable to reliably modify project files/code. The desktop global state still contains the expected project roots under thread-writable-roots, including the affected project directories, so this does not look like a simple missing writable-root grant.

This strongly matches #40700 rather than a WSL-only configuration problem. It also suggests that setting CODEX_CLI_PATH to a manually staged .sandbox-bin\codex.exe is not a safe workaround because it may create a desktop/runtime/sandbox mismatch even if startup succeeds.

pieyixi · 2 days ago

I can independently reproduce this exact regression on Windows 10:

  • Codex Desktop: 26.820.7780.0 (Microsoft Store/MSIX)
  • Bundled CLI: codex-cli 0.150.0-alpha.8
  • Windows 10 22H2 x64, OS build 19045.6466
  • Previous working version: 26.818.8289.0
  • Secondary AppX volume: D:\WindowsApps, exposed through the standard C:\Program Files\WindowsApps package junction

The four bundled Windows CLI executables exist, but they are Application Protected. Codex attempts to relocate them with Node.js fs.copyFileSync() into %LOCALAPPDATA%\OpenAI\Codex\bin\<hash>. The copy fails with:

The specified file could not be encrypted.

This is consistent with ERROR_ENCRYPTION_FAILED / Win32 error 6000. The destination cache contains rg.exe, but the expected codex.exe group is absent. Codex then reports the misleading downstream error “Unable to locate the Codex CLI binary.”

A byte-identical external copy of the bundled codex.exe runs correctly, and pointing CODEX_CLI_PATH to it restores Desktop startup. The MSIX manifest declares Windows.Desktop MinVersion="10.0.19041.0", so build 19045 is within the package's declared minimum version.

My separate report was #40791; I am closing it as a duplicate so tracking remains centralized here.

Faye-663 · 2 days ago

Additional reproduction on Windows Native with Codex Desktop 26.820.7780.0: the app fails with “Unable to locate the Codex CLI binary.” The bundled codex.exe exists but is marked Archive, Encrypted; copying it to a temporary directory fails with “The specified file could not be encrypted,” and running it directly returns “Access is denied.” No usable per-user staging copy exists. CODEX_CLI_PATH is unset and no WindowsApps permissions or package files were modified. This further confirms a WindowsApps/MSIX bundled executable relocation failure on the Windows-native startup path.

RenAhsAcme · 2 days ago

I'm upgrading my ChatGPT App to 26.820.7780.0 from App's internal button, and I'm sure the settings or configs about WindowsApps directory, and env variables are never modified manually. The OS env is Windows 11 Enterprise 25H2 26220.9223 (but as far as I can see, maybe this is not main factor). When launched App, a loading window can be seen briefly, then a error was thrown back like this:

<img width="838" height="251" alt="Image" src="https://github.com/user-attachments/assets/13132b5e-9e8e-4108-8e21-52dd1a9667a9" />

uhhh... According to this clue, I tried to run app\resources\codex.exe, but Access is denied. Adding a new variable CODEX_CLI_PATH pointing to app\resources\codex.exe can make it success. So it may be the relocation failure which happened during the updating time?

Ackey-2 · 2 days ago

Confirmed on another Windows x64 installation.

Environment:

  • OpenAI.Codex 26.820.7780.0 x64
  • InstallLocation: C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0
  • AppX default volume: D:\WindowsApps
  • CODEX_CLI_PATH: not set

Read-only checks showed the bundled resources have the Encrypted attribute:

  • app\resources\codex.exe
  • app\resources\codex
  • app\resources\cua_node
  • app\resources\rg.exe

Before recovery, the per-user runtime cache under %LOCALAPPDATA%\OpenAI\Codex did not contain usable materialized executables for codex.exe / node.exe / rg.exe.

I applied the recovery script from:
https://github.com/openai/codex/issues/40700#issuecomment-5419391502

without changing WindowsApps ACLs, ownership, package files, encryption attributes, CODEX_CLI_PATH, or Codex sessions/config.

Recovered cache paths:

  • Windows CLI: %LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0
  • cua_node: %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\950613ca46815e82
  • Windows rg: %LOCALAPPDATA%\OpenAI\Codex\bin\b91d382ea836415f
  • WSL CLI: %USERPROFILE%\.codex\bin\wsl\bf0dd1e87d338bce
  • WSL rg: %USERPROFILE%\.codex\bin\wsl\1a4f6f66dd2f3710

Verification after recovery:

  • codex-cli 0.150.0-alpha.8
  • node v24.19.0
  • ripgrep 15.2.0 (rev e89fff89ac)

ChatGPT Desktop restarted successfully, and codex.exe is now running from the per-user cache path.

This supports the diagnosis that the desktop app's WindowsApps resource relocation path needs to handle ERROR_ENCRYPTION_FAILED / Application Protected or EFS-backed package resources, instead of surfacing the secondary “Unable to locate the Codex CLI binary” error.

Pawnie1 · 2 days ago

Same regression here, plus a verified workaround for the Windows-native path that does not require downgrading.

Environment:

  • OpenAI.Codex 26.820.7780.0 (Microsoft Store / MSIX), single AppX volume on C:, no junctions
  • Windows 11 10.0.26200.0 x64
  • Bundled CLI: codex-cli 0.150.0-alpha.8
  • CODEX_CLI_PATH unset, Windows-native agent (no WSL)

This confirms the diagnosis above. All four packaged executables report Archive, Encrypted, and cipher /c reports Compatibility Level: Application Protected. copyFileSync out of the package fails:

$res = (Get-AppxPackage OpenAI.Codex).InstallLocation + '\app\resources'
Copy-Item -LiteralPath "$res\rg.exe" -Destination $env:TEMP -Force
# IOException: The specified file could not be encrypted.   (0x80071770)

One detail worth adding: a stream copy of the same file succeeds, because it writes plaintext bytes instead of asking the destination to inherit EFS.

$in = [IO.File]::OpenRead("$res\rg.exe"); $out = [IO.File]::Create("$env:TEMP\rg.exe")
$in.CopyTo($out); $out.Close(); $in.Close()
# OK - destination attributes: Archive

So the source is readable by the user; only the CopyFile encryption-preserving path fails. That supports COPY_FILE_ALLOW_DECRYPTED_DESTINATION (proposed in #38696) as the right upstream fix.

The missing piece: how the destination directory name is derived

#38696 describes pre-staging into <descriptor-hash> but not how to compute it. From app.asar in 26.820.7780.0, the relocation helper derives it as:

inner_i  = sha256(bytes of file_i).hex()            # lowercase
material = concat over i of:  name_i + "\0" + inner_i + "\0"
dir      = sha256(utf8(material)).hex()[0:16]

Two groups are relocated independently, and file order matters:

| group | files, in order | destination |
| --- | --- | --- |
| CLI | codex.exe, codex-code-mode-host.exe, codex-windows-sandbox-setup.exe, codex-command-runner.exe | %LOCALAPPDATA%\OpenAI\Codex\bin\<hash>\ |
| ripgrep | rg.exe | %LOCALAPPDATA%\OpenAI\Codex\bin\<hash>\ |

On the next launch the app validates each staged file by size and SHA-256 (mtime is not checked) and returns early, so a correctly pre-staged directory makes it skip the failing copy entirely.

Verified workaround

$ErrorActionPreference = 'Stop'
$pkg = Get-AppxPackage -Name OpenAI.Codex
if ($pkg -eq $null) { throw "OpenAI.Codex package is not installed." }
$res     = Join-Path $pkg.InstallLocation "app\resources"
$binRoot = Join-Path $env:LOCALAPPDATA "OpenAI\Codex\bin"

function Get-GroupHash($names) {
  $sb = New-Object System.Text.StringBuilder
  foreach ($n in $names) {
    $h = (Get-FileHash -LiteralPath (Join-Path $res $n) -Algorithm SHA256).Hash.ToLower()
    [void]$sb.Append($n); [void]$sb.Append([char]0); [void]$sb.Append($h); [void]$sb.Append([char]0)
  }
  $bytes = [Text.Encoding]::UTF8.GetBytes($sb.ToString())
  $outer = ([Security.Cryptography.SHA256]::Create().ComputeHash($bytes) |
            ForEach-Object { $_.ToString("x2") }) -join ''
  return $outer.Substring(0,16)
}

function Copy-Group($names) {
  $target = Join-Path $binRoot (Get-GroupHash $names)
  if (-not (Test-Path -LiteralPath $target)) { New-Item -ItemType Directory -Path $target -Force | Out-Null }
  foreach ($n in $names) {
    $d = Join-Path $target $n
    $srcLen = (Get-Item -LiteralPath (Join-Path $res $n)).Length
    if ((Test-Path -LiteralPath $d) -and ((Get-Item -LiteralPath $d).Length -eq $srcLen)) { continue }
    $in = [IO.File]::OpenRead((Join-Path $res $n)); $out = [IO.File]::Create($d)
    try { $in.CopyTo($out) } finally { $out.Close(); $in.Close() }
  }
  return $target
}

Copy-Group @('codex.exe','codex-code-mode-host.exe','codex-windows-sandbox-setup.exe','codex-command-runner.exe')
Copy-Group @('rg.exe')

Result on my machine: the app starts normally and the sidecar runs from the staged path.

Id   ProcessName  Path
8180 codex        C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\d0097be4feba73d0\codex.exe

codex.exe --version from that directory reports codex-cli 0.150.0-alpha.8, and the staged directories survive relaunch (the app validates them and skips the copy).

Caveats: the hashes change with every app update, so this has to be re-run after each Store update until the copy path is fixed upstream. Nothing under WindowsApps is modified, and no ACLs, ownership, or encryption settings are changed.

zzx-007-d · 2 days ago

I can reproduce this on Windows x64 with the Microsoft Store package OpenAI.Codex version 26.820.7780.0.

Startup fails immediately with:

ChatGPT failed to start. Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

Additional checks from PowerShell:

$p = Get-AppxPackage OpenAI.Codex
$p.InstallLocation
# C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

Test-Path "$($p.InstallLocation)\app\resources\codex.exe"
# True

Test-Path "$($p.InstallLocation)\app\resources\bin\codex.exe"
# False

So the bundled CLI is present at app\resources\codex.exe, but not at app\resources\bin\codex.exe.

I also tried setting CODEX_CLI_PATH directly to the bundled executable:

[Environment]::SetEnvironmentVariable(
  "CODEX_CLI_PATH",
  "$($p.InstallLocation)\app\resources\codex.exe",
  "User"
)

The variable resolves correctly, but attempting to execute the packaged binary directly fails with:

Program 'codex.exe' failed to run: Access is denied

I have not manually modified WindowsApps permissions, ownership, or ACLs. This looks consistent with the same WindowsApps bundled-executable relocation/access regression described in this issue.

gagaeasy · 2 days ago

Independent reproduction and successful recovery on another Windows x64 machine.

Environment:

  • Windows 10.0.26200.0 x64
  • OpenAI.Codex 26.820.7780.0
  • Default AppX volume: D:\WindowsApps
  • Registered install location: C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0
  • The registered C: location is a standard junction targeting the same package under D:\WindowsApps
  • The package status was Ok

The desktop app had worked before this release. On cold start with 26.820.7780.0, the first relevant failures were:

bundled_executable_relocation_failed
operation=copy_file
executableName=codex.exe
sourceKind=windowsapps
errno=-4094
code=UNKNOWN

The source was the packaged app\resources\codex.exe, and the destination was a .staging-d0097be4feba73d0-* directory under %LOCALAPPDATA%\OpenAI\Codex\bin. The same launch also failed to relocate cua_node with copy_directory. Only after those failures did the app report Unable to locate the Codex CLI binary and Desktop bootstrap failed.

The packaged resources existed and had the Encrypted / Application Protected behavior. Executing the packaged codex.exe directly returned Access Denied. Setting CODEX_CLI_PATH to that protected package path did not help and was removed.

I applied the dynamic materialization approach from this comment, using buffered FileStream reads/writes, staging directories, SHA-256 verification, and atomic directory publication. No WindowsApps ACL, ownership, package file, encryption setting, session, or Codex configuration was changed.

Computed cache IDs for this official package:

Windows CLI   d0097be4feba73d0
cua_node      950613ca46815e82
Windows rg    b91d382ea836415f
WSL CLI       bf0dd1e87d338bce
WSL rg        1a4f6f66dd2f3710

Verification before relaunch:

codex-cli 0.150.0-alpha.8
node v24.19.0
ripgrep 15.2.0
cua_node source files: 4018
cua_node cached files: 4018
CODEX_CLI_PATH: unset

Cold-launch verification succeeded. The running sidecar was loaded from the versioned user cache:

%LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0\codex.exe

The new desktop log contained:

hostId=local initialized=true next=connected

and contained zero occurrences of:

bundled_executable_relocation_failed
Unable to locate the Codex CLI binary
Desktop bootstrap failed

This confirms that the package binaries are valid and that the fatal failure is in the WindowsApps-to-user-cache copy path. Installing Store apps on a secondary AppX volume exposes the regression, but changing the user's default Store volume should not be required. The durable fix should make the relocation helper support an Application Protected source and an ordinary decrypted destination, with the current hash verification and atomic publication retained.

muxia51821 · 2 days ago

Additional diagnostics + a verified no-rollback workaround (CODEX_CLI_PATH with a Windows-native CLI)

Environment: Windows 11 Pro 25H2 (build 26200), OpenAI.Codex 26.820.7780.0 (MSIX/Store), ChatGPT Plus. Same failure chain as this issue: bundled_executable_relocation_failed (copy_file/copy_directory, errno -4094 UNKNOWN) → app-server fatal → startup dialog.

1. Verified workaround — CODEX_CLI_PATH to a real Windows exe works.
Setting a user env var to a standalone Windows-native binary restored normal startup immediately:

CODEX_CLI_PATH = C:\Users\<user>\AppData\Roaming\npm\node_modules\@openai\codex\node_modules\@openai\codex-win32-x64\vendor\x86_64-pc-windows-msvc\bin\codex.exe

Two details that matter: (a) it must be the real exe under vendor\...\bin, not an npm .cmd shim (likely the EINVAL-on-.cmd reported in #40752); (b) version skew between app 26.820 and CLI 0.149.1 is tolerated so far (chat/code review all work). Note the bundled cua_node runtime still fails to relocate (copy_directory), so computer-use features remain unavailable under this workaround.

2. The app's own user-data profile is also Application-Protected EFS — backup before Reset is impossible with normal tools.
%LOCALAPPDATA%\Packages\OpenAI.Codex_2p2nqsd0c76g0\LocalCache\Roaming\Codex\web\Codex\Default (Cookies, Local Storage, GCM Store…) shows Archive, Encrypted. Copy-Item / CopyFileW fails there exactly like the package relocation does; only byte-level read (ReadAllBytes → plain write) succeeds. Practical consequences: (a) any support flow advising Reset/uninstall should warn users that login/session data cannot be backed up with normal copy tools and will be destroyed by Reset; (b) Repair re-deploys from the same encrypted source and does not resolve the issue (confirmed).

3. Hint for the durable fix.
On the same files where CopyFileW-based copy fails (-4094 / ERROR_ENCRYPTION_FAILED family), a plain sequential read (CreateFile + ReadFile) succeeds for the same user process. Switching the relocation step from CopyFileW to a stream read/write (or reusing a size/hash-verified existing per-user runtime instead of purging it) would likely fix startup without changing how the MSIX is shipped.

Corroborating the multi-volume reports above: this machine originally had the package on E:\WindowsApps; the self-triggered Store update landed the new registration on C:\Program Files\WindowsApps.

Agony-frank · 2 days ago

Additional confirmation and workaround from another affected Windows user:

  • Windows 11 Pro, x64, build 26200
  • Startup failed with: Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.
  • Moving the ChatGPT/Codex desktop app installation to the system drive (C:) resolved the problem and the app started normally.

This adds evidence that the failure is related to MSIX/AppX package placement on a secondary drive or the relocation of bundled executables from a non-system app volume. Testing install/move behavior between C: and a secondary AppX volume may help reproduce the issue. The app should ideally handle this location transparently rather than requiring users to move it back to C:.

HowToSaveMyLife · 2 days ago

I solved this problem using the following method. This method comes from a previous comment, but it has some problem with \$in.Close();

$src = Join-Path $package.InstallLocation 'app\resources'
$dst = "$env:LOCALAPPDATA\OpenAI\Codex\bin"
New-Item -ItemType Directory -Force -Path $dst | Out-Null
'codex.exe',
'codex-code-mode-host.exe',
'codex-command-runner.exe',
'codex-windows-sandbox-setup.exe',
'rg.exe' | ForEach-Object {
    $sourceFile = Join-Path $src $_
    $targetFile = Join-Path $dst $_

    $inputStream = [IO.File]::OpenRead($sourceFile)
    try {
        $outputStream = [IO.File]::Create($targetFile)
        try {
            $inputStream.CopyTo($outputStream)
        }
        finally {
            $outputStream.Dispose()
        }
    }
    finally {
        $inputStream.Dispose()
    }
}
[Environment]::SetEnvironmentVariable(
    'CODEX_CLI_PATH',
    "$dst\codex.exe",
    'User'
)
muxia51821 · 1 day ago

@HowToSaveMyLife thanks, your script works! I ended up going a slightly lazier route though — no copying at all, just pointed CODEX_CLI_PATH at an existing standalone CLI and the app started right away.

npm install -g @openai/codex   # skip if you already have it
[Environment]::SetEnvironmentVariable('CODEX_CLI_PATH', "$env:APPDATA\npm\node_modules\@openai\codex\node_modules\@openai\codex-win32-x64\vendor\x86_64-pc-windows-msvc\bin\codex.exe", 'User')

one thing that got me at first: it has to be the real exe under vendor\...\bin — the .cmd shim npm puts on PATH won't work (probably the same EINVAL as #40752).

been running app 26.820 with CLI 0.149.1 for a few hours now, chat and code review all fine, so the version mismatch doesn't seem to matter much. and when a newer CLI lands it's just npm i -g @openai/codex@latest — nothing to redo whenever the desktop app updates itself.

only downside is the same as your method: cua_node still can't relocate, so computer-use stuff stays broken either way. hopefully the next app build just fixes the relocation properly.

Drifter-rookie · 1 day ago

I’m seeing the same regression after the Microsoft Store auto-update to 26.820.7780.0.

The app was working normally before the update. After the update and a reboot, it immediately started failing with:

ChatGPT failed to start. Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

A few checks from my machine:

  • Package: OpenAI.Codex 26.820.7780.0 x64
  • Install location: C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0
  • Both app\resources\codex and app\resources\codex.exe are present.
  • Both files show Archive, Encrypted attributes.
  • Copying the bundled codex file to %TEMP% fails with the Windows error: The specified file could not be encrypted.
  • Running the bundled codex.exe --version directly fails with Access denied / ApplicationFailedException.
  • My separately installed Codex CLI still works normally (codex-cli 0.135.0), so this does not look like a general CLI/PATH problem.
  • I have not changed WindowsApps permissions or ownership, and I have not set CODEX_CLI_PATH as a workaround.

The timing is very clear on my side: working before the Store update → auto-update to 26.820.7780.0 → reboot → app no longer starts.

I’m keeping the installation unchanged for now and waiting for an official fix, so I can provide more diagnostics if needed.

Chang-Yo · 1 day ago

You can just download ChatGPT beta. It can successfully launch.

Drifter-rookie · 1 day ago

Update: moving ChatGPT back to C: fixed the issue for me.

Windows Settings showed ChatGPT installed on D:, and my default AppX volume was also D:\WindowsApps. I used:

Settings → Apps → Installed apps → ChatGPT → Move → C:

After that, 26.820.7780.0 launched normally again. I did not set CODEX_CLI_PATH or change any WindowsApps permissions.

etraut-openai contributor · 1 day ago

Thanks for the bug report. We understand the problem and are working on expediting a fix.

theddynur363-dev · 1 day ago

I hit what appears to be the same Windows Codex Desktop issue.

Environment:

  • Windows 11
  • Codex Desktop: 26.820.7780.0
  • Initial error: Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

What I found:

  1. Codex Desktop could not locate its CLI automatically.
  1. where.exe codex returned only the npm shims:

C:\Users\lenovo\AppData\Roaming\npm\codex
C:\Users\lenovo\AppData\Roaming\npm\codex.cmd

  1. A native codex.exe did exist under:

C:\Users\lenovo\AppData\Local\OpenAI\Codex\bin\<hash>\codex.exe

  1. Pointing CODEX_CLI_PATH to that executable allowed the desktop app to launch, but that binary turned out to be:

codex-cli 0.140.0-alpha.2

  1. After that, one existing thread failed to open with:

failed to read thread
rollout-...jsonl does not start with session metadata

I inspected the corresponding .jsonl file. The file itself was valid UTF-8 JSON, started directly with {, and the first record was:

"type":"session_meta"

The same session metadata showed it had originally been written by:

cli_version: 0.149.0-alpha.4.1

So the desktop app was effectively trying to read a session written by 0.149.0-alpha.4.1 using the much older 0.140.0-alpha.2 CLI.

I then updated the npm Codex CLI:

npm install -g @openai/codex@latest

This installed:

codex-cli 0.150.0

I changed CODEX_CLI_PATH to point directly to the native 0.150.0 codex.exe under the npm package:

...\@openai\codex-win32-x64\vendor\x86_64-pc-windows-msvc\bin\codex.exe

After fully restarting Codex Desktop:

  • the app launched normally;
  • the previously broken thread opened normally;
  • no modification of the .jsonl session file was necessary.

So in my case, the issue appears to be a combination of:

  • Codex Desktop failing to locate/select the correct bundled CLI on Windows;
  • the workaround/fallback selecting an outdated cached CLI;
  • that older CLI then failing to read a newer session format.

Current workaround: manually point CODEX_CLI_PATH to an up-to-date native codex.exe.

R2Pitou · 1 day ago

I thought AppX had thinged a thing and borked the install by thinging things. This remains the best explanation I have managed to form about package managers.

Get-AppxPackage -Volume (Get-AppxVolume -Path "D:\") -Name OpenAI.Codex correctly finds OpenAI.Codex 26.820.7780.0, while querying the C: AppX volume does not.

Inspecting the reported install path with Get-Item -Force shows that:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

is actually a junction pointing to the physical package under D:\WindowsApps.

So Windows Package Manager has successfully thinged the thing, and I retract the accusation that it randomly moved Codex to C:. :))

Unfortunately, Codex still does not start.

Get-AppxPackage OpenAI.Codex | Format-List * reports:

Version : 26.820.7780.0
Status : Ok
IsPartiallyStaged : False

The bundled CLI also physically exists at:

app\resources\codex.exe

under the package.

However, launching Codex still fails with:

Unable to locate the Codex CLI binary.

Trying to execute the packaged CLI directly with & "<package-path>\app\resources\codex.exe" --version returns:

Access is denied

I also tried moving the package explicitly to the configured D: AppX volume with Move-AppxPackage -Package $pkg.PackageFullName -Volume $vol -Verbose. AppX reported Operation completed, and the package remains correctly associated with the D: AppX volume, but the Codex startup failure is unchanged.

So this does not appear to be caused by the non-system AppX volume itself. The package is registered, status is Ok, the CLI payload exists, and the package is on the expected volume.

Also an important note: Restarting Windows did not fix the issue! :))

P.S. I missed the reply from @etraut-openai above.
I shall shut up now and wait for the patch. :))

Xiang-Think · 1 day ago

I hit the same issue on OpenAI.Codex 26.820.7780.0 and did some read-only forensics after recovering the app. I found fairly strong evidence that this is a regression involving a secondary Appx Volume, rather than a missing codex.exe.

Previous version was already on D: and worked

This was not a case where the 26.820 update unexpectedly moved the app from C: to D:.

Windows AppX event history shows:

  • 26.818.8289.0 was staged and registered to Appx Volume D: on Aug 24.
  • Its desktop JS was running from:

D:\WindowsApps\OpenAI.Codex_26.818.8289.0_...\app\resources\app.asar

  • The CLI successfully spawned and completed the initialization handshake.
  • On Aug 26, Windows updated 26.818.8289.0 -> 26.820.7780.0 on the same D: Appx Volume.
  • AppX then moved the old package from:

D:\WindowsApps\OpenAI.Codex_26.818.8289.0_...
into D:\WindowsApps\Deleted\...

So the previous build definitely worked while physically deployed on D:.

What changed with 26.820

On the first failing 26.820 launches, the JS stack was still executing from:

D:\WindowsApps\OpenAI.Codex_26.820.7780.0_...\app\resources\app.asar

but bundled_executable_relocation_failed reported this sourcePath:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_...\app\resources\codex.exe

The relocation destination was:

%LOCALAPPDATA%\OpenAI\Codex\bin\.staging-...\codex.exe

The copy failed with errno=-4094, code=UNKNOWN, syscall=copyfile, and immediately afterwards bootstrap failed with:

Unable to locate the Codex CLI binary

The package itself did contain:

app\resources\codex.exe

so this was not simply a missing CLI payload.

Moving D: -> C: immediately fixed it

I used Windows Settings to move the same installed package from D: to C:.

No:

  • version update
  • reinstall
  • reset
  • permission change
  • CODEX_CLI_PATH change

was performed.

Immediately afterwards, the bundled CLI was successfully relocated to:

%LOCALAPPDATA%\OpenAI\Codex\bin\<hash>\codex.exe

and Codex launched normally.

The relocated codex.exe is byte-for-byte identical to the bundled app\resources\codex.exe.

One additional static-analysis clue

In the installed app.asar, the WindowsApps detection logic appears to check specifically for the normalized substring:

\program files\windowsapps\

which does not generalize to secondary Appx Volume paths such as:

D:\WindowsApps\...

I cannot prove which layer first produces the canonical C: path (Codex, Electron process.resourcesPath, or AppX projection), but the evidence strongly suggests a 26.818 -> 26.820 regression in bundled CLI relocation/fallback handling on secondary Appx Volumes.

I can provide redacted failure/success log excerpts and relevant AppX event IDs if useful.

Sceneryyyy · 1 day ago

I can reproduce what appears to be the same bundled-runtime relocation/bootstrap issue on a newer build, but with one important difference: the bundled files are NOT encrypted on my machine.

Environment

  • Codex Desktop: 26.820.9563.0
  • Install:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.9563.0_x64__2p2nqsd0c76g0

  • Windows x64
  • Microsoft Store / MSIX install

Findings

  1. All required bundled executables are present under app\resources:
  • codex.exe
  • codex-code-mode-host.exe
  • codex-command-runner.exe
  • codex-windows-sandbox-setup.exe
  1. The bundled files are readable and hashable.

For app\resources\codex, Get-Item reports only:

Attributes = Archive

There is no Encrypted attribute.

Manual Copy-Item from WindowsApps to a normal user-writable directory succeeds.

  1. However, executing the bundled Windows binary directly from WindowsApps fails:

& "$pkg\app\resources\codex.exe" --version

Result:

Access is denied

The exact same executable copied to %TEMP% runs successfully:

codex-cli 0.150.0-alpha.8
exit code 0

  1. %LOCALAPPDATA%\OpenAI\Codex\bin contains many empty staging directories:

.staging-b91d382ea836415f-...
.staging-d4ec92c58943bf91-...
.staging-c6c4820dcd243daa-...
...

Every recent .staging-* directory is empty.

There is one older complete runtime directory:

%LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0

It contains all four executables and they execute normally.

  1. CODEX_CLI_PATH was originally unset.

As a workaround I set:

CODEX_CLI_PATH =
%LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0\codex.exe

After restarting Codex Desktop, the app and the local execution host fully recovered.

Independent checks after the workaround:

  • PowerShell 7 x64: PASS
  • child PowerShell process: PASS
  • delayed child process: PASS
  • cmd.exe: PASS
  • Python: PASS
  • rg.exe: PASS
  • codex.exe --help: PASS
  • code-mode host: PASS
  • command runner / child process spawning: PASS

The resolved codex/rg paths are now under:

%LOCALAPPDATA%\OpenAI\Codex\bin\...

rather than WindowsApps.

Additional observations

  • Bundled codex.exe and the working LocalAppData runtime both report codex-cli 0.150.0-alpha.8.
  • SHA256 differs, apparently due to build/package differences, but this is not a CLI version downgrade.
  • app.asar contains references to CODEX_CLI_PATH, and the override is honored by Desktop.
  • No WindowsApps ACL/ownership changes were made.

Conclusion

This suggests the failure may be broader than the encrypted/EFS case originally reported in #40700.

On this machine:

  • bundled runtime exists
  • bundled runtime is not marked Encrypted
  • bundled runtime can be read and manually copied
  • execution directly from WindowsApps returns Access is denied
  • automatic relocation repeatedly leaves empty .staging-* directories
  • an already-relocated LocalAppData runtime works normally
  • explicitly pointing CODEX_CLI_PATH to that runtime restores the entire Desktop execution toolchain

So the underlying problem appears to be in the WindowsApps bundled-runtime relocation/bootstrap path rather than a missing Codex CLI or a project/shell issue.

Carl-coder9527 · 1 day ago

I can reproduce this issue on Windows 11 with ChatGPT/Codex Desktop version 26.820.9563.0.

Symptoms:

  • Launching ChatGPT briefly creates a ChatGPT process.
  • The ChatGPT process then disappears and only Codex background processes remain.
  • No desktop GUI window appears.
  • I previously received the error:

"Unable to locate the Codex CLI binary.
Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex."

Troubleshooting already attempted:

  • Check for Updates
  • Windows app Repair
  • Restart Windows
  • Windows app Reset
  • Uninstall and reinstall the official ChatGPT app from Microsoft Store

The issue still reproduces after all of the above.

Additional information:

  • Installed desktop version: 26.820.9563.0
  • Standalone Codex CLI 0.150.1 installs and works normally on the same machine.
  • The CLI can access local repositories and execute PowerShell commands successfully.

This suggests the account/model/standalone CLI are working, while the Windows desktop app startup path is still failing.

Pribelady · 22 hours ago

Windows 26.820 bundled Codex CLI failure: from “binary not found” to the actual relocation bug

A beginner-friendly, evidence-led investigation of ChatGPT/Codex Desktop 26.820.7780.0 on Windows. No prior knowledge of Electron, MSIX, WindowsApps, bundled executables, or hash caches is assumed.

This report is intended as a detailed follow-up to openai/codex#40700. It documents not only the final diagnosis, but how the diagnosis was reached from an initially unknown failure.

Executive summary

The application displayed:

ChatGPT failed to start.

Unable to locate the Codex CLI binary.
Set CODEX_CLI_PATH or ensure the Electron resources include bin/codex.

The same Desktop installation had worked on August 4, 2026. When it was opened again on August 26, 2026, build 26.820.7780.0 showed the error above. That timeline later explained why an August 4 cache existed but did not match the newer package.

Read-only inspection of the packaged Desktop program recovered the two executable-resolution branches directly relevant to this incident:

Windows successfully starts ChatGPT.exe
          ↓
Desktop needs a Codex executable
          ↓
Is a usable CODEX_CLI_PATH override configured?
          │
   ┌──────┴──────┐
   │ yes         │ no
   ↓             ↓
Use that exact   Find the four bundled executables
executable      in the current app resources
   │             ↓
   │          Read and hash the four files
   │             ↓
   │          Calculate the bundle-hash cache path
   │             ↓
   │          Reuse a matching cache, or create one
   │          through staging/copy/verify/rename
   │             ↓
   └──────┬──────┘
          ↓
Return the final codex.exe path and start it

This immediately explains why the standalone workaround worked: when a usable CODEX_CLI_PATH was present, Desktop selected that executable and did not need to calculate the bundled hash, validate the bundled cache, or copy the packaged files.

The original failure occurred only on the second branch. The bundled files were present, discovery and hashing worked, and the first failing operation was copy_file while Desktop tried to create the current bundle cache.

Two recovery paths were verified:

  1. Workaround: install a standalone Codex CLI and point CODEX_CLI_PATH to it. This bypasses the bundled path completely.
  2. Advanced bundled recovery: byte-stream copy the four signed package executables into a staging directory, verify their size, SHA-256, and Authenticode signatures, then rename the directory to the bundle-hash cache name. This restores use of Desktop's bundled CLI without modifying WindowsApps.

The second method restores the machine, but does not fix the Desktop regression. It proves that Desktop can validate and reuse an already-correct cache; it does not prove that Desktop 26.820.7780.0 can automatically create that cache from an empty state.

1. Tested package and executable-resolution flow

The affected application was registered as:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

<img width="664" height="114" alt="Image" src="https://github.com/user-attachments/assets/e0002d23-b2ee-40c8-9fe8-c3f83ba0d989" />

Get-Process ChatGPT | Select-Object Path confirmed that the running ChatGPT.exe came from this package. The packaged Desktop logic then resolves the Codex executable using the two-branch flow shown above: an explicit override first, otherwise the bundled resolver.

2. What the bundled branch is supposed to do

The installed package contains these four Windows executables under app\resources:

codex.exe
codex-code-mode-host.exe
codex-windows-sandbox-setup.exe
codex-command-runner.exe

Desktop does not simply search the whole disk for codex.exe. The packaged program code supplies its own resourcesPath, chooses the expected filename for Windows, and prepares a versioned runtime cache under:

%LOCALAPPDATA%\OpenAI\Codex\bin\<16-character bundle hash>

The locally inspected minified functions were labelled JP, BP, and rF. Those names are implementation identifiers from this build, not a public API. Once no usable explicit override has been selected, the bundled branch is:

Locate the four files under resourcesPath
                 ↓
Read and hash each source file
                 ↓
Combine filenames + hashes into one bundle hash
                 ↓
Derive the expected 16-character cache directory
                 ↓
          ┌──────┴────────┐
          │               │
 valid matching cache    no valid cache
          │               │
          │          create staging directory
          │               ↓
          │          copy four files
          │               ↓
          │          verify destination
          │               ↓
          │          rename staging to hash
          └──────┬────────┘
                 ↓
Return final codex.exe path and start it

Hashing and relocation are consecutive stages, not two competing ways to find the executable.

  • Hashing identifies the exact four-file bundle and determines the expected cache directory.
  • Relocation creates that cache when it is missing.
  • Destination validation checks size and hash, so a directory with the correct name but modified contents is not blindly trusted.

Hashing only requires reading the package files. It does not require copying them first. That distinction becomes central to this bug.

3. The investigation, in the order it actually happened

Step 1 — Confirm the running Desktop package and whether its bundled files exist

The first useful question was not whether a global codex command existed, but whether the affected Desktop package actually contained the executables its bundled branch expected.

Get-AppxPackage *Codex* |
  Select-Object Name, Version, InstallLocation

Observed:

Name            : OpenAI.Codex
Version         : 26.820.7780.0
InstallLocation : C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0

The running process path was also checked directly:

Get-Process ChatGPT -ErrorAction SilentlyContinue |
  Select-Object Id, ProcessName, Path

The active ChatGPT.exe came from the registered C: package. Its resources directory was then listed:

$pkg = Get-AppxPackage OpenAI.Codex
Get-ChildItem "$($pkg.InstallLocation)\app\resources" -Force |
  Select-Object Name, Length

The result included codex.exe and all three Windows sibling executables. The bundled executable was not literally absent. The remaining possibilities were path generation, validation, relocation, or process creation.

“Unable to locate” ≠ “the package contains no codex.exe”

Step 2 — Use an explicit CLI as a controlled substitute

The standalone installer had placed a native Windows CLI at a user-directory path, even though that directory was not in PATH.

The resolver flow extracted later showed why this was a clean experiment: a usable CODEX_CLI_PATH is selected before the bundled hashing/cache branch. The test therefore changed one input:

Before: Desktop A → automatic bundled B → failure
Test:   Desktop A → explicit standalone C → success

A user-level CODEX_CLI_PATH was used because a process-local PowerShell variable is not a reliable assumption when launching a packaged app through Windows activation.

[Environment]::SetEnvironmentVariable(
  'CODEX_CLI_PATH',
  'C:\Users\<user>\.codex\packages\standalone\releases\0.149.1-x86_64-pc-windows-msvc\bin\codex.exe',
  'User'
)

Desktop opened, and a real local-file task succeeded.

<img width="664" height="114" alt="Image" src="https://github.com/user-attachments/assets/d159161a-3278-409a-83f4-a9a3bb89eb34" />

This established:

  • the Desktop GUI was not generally broken;
  • the account was not the primary startup blocker;
  • Desktop could communicate with a valid native Windows Codex CLI;
  • the failure was concentrated in the default bundled-CLI discovery/preparation path.

It restored use and isolated the faulty branch, but it did not yet reveal which bundled operation failed.

Step 3 — Determine whether Windows failed to start the app or the app failed internally

Windows AppModel events from the original failure window were queried:

$start = Get-Date '2026-08-26 19:20:00'
$end   = Get-Date '2026-08-26 19:35:00'

Get-WinEvent -LogName 'Microsoft-Windows-AppModel-Runtime/Admin' |
  Where-Object {
    $_.TimeCreated -ge $start -and
    $_.TimeCreated -le $end -and
    $_.Message -match 'OpenAI.Codex|ChatGPT|codex'
  }

Windows recorded successful package-container creation and successful ChatGPT.exe process creation. Therefore the problem was not Start-menu registration, AppID activation, or failure to create the Desktop process.

The Codex SQLite log database was then opened read-only and queried for the same time window. It contained zero CLI log entries.

The combined evidence was:

Windows creates ChatGPT.exe                    yes
Codex CLI produces any startup log             no
Desktop shows “Unable to locate”                yes

This placed the failure after Desktop started but before a Codex CLI process successfully began running.

Step 4 — Recover the executable-resolution flow from the packaged Desktop program

At this point external checks could not distinguish path construction from relocation. The packaged Electron archive was read in binary mode, without modifying or unpacking it, and the exact error string was located:

@'
path = r"C:\Program Files\WindowsApps\OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0\app\resources\app.asar"
needle = b"Unable to locate the Codex CLI binary"

with open(path, "rb") as f:
    data = f.read()

position = data.find(needle)
print(position)
print(data[position-4000:position+7000].decode("utf-8", errors="replace"))
'@ | python -

This established that the error is thrown by Desktop when its resolver returns no valid launch configuration. It is not an error emitted by codex.exe.

Further read-only searches progressively recovered the relevant definitions and call sites:

  • the resolver entry and its explicit-override versus bundled selection;
  • parsing and use of CODEX_CLI_PATH;
  • JP(resourcesPath) for the bundled executable candidate;
  • uF(...) for a %LOCALAPPDATA% destination path;
  • BP(...) for WindowsApps-specific preparation;
  • rF(...) for source hashing, cache validation, staging, copying, rename, and destination verification.

This changed the leading hypothesis from “the resolver probably constructs the wrong path” to a testable relocation pipeline:

stat_source
hash_source
calculate bundle hash
validate existing destination
mkdir_destination
mkdir_staging
copy_file × 4
rename_staging
stat_destination
hash_destination

Step 5 — Inspect the runtime cache and compare old versus current bundles

The resolver's destination root was inspected:

$dest = Join-Path $env:LOCALAPPDATA 'OpenAI\Codex\bin'

Get-ChildItem $dest -Force -Recurse -ErrorAction SilentlyContinue |
  Select-Object FullName, Length, LastWriteTime, Attributes

Only two older hash directories existed:

3e42d49ad3e35a50   → rg.exe
d7e8094cfb76a267   → an older four-file Codex bundle from August 4

The old codex.exe size was 358,182,192 bytes. The current package's codex.exe was 307,568,432 bytes. The old directory was therefore not the cache for the current package.

An old cache is not a fallback alias. Desktop derives a new directory from the current files and validates its contents. When the bundled artifacts change, their hashes and bundle directory change.

Step 6 — Reproduce the current bundle hash

The extracted algorithm was applied to the four current package files:

  1. Calculate SHA-256 for each file in a fixed order.
  2. For each file, append filename + NUL + lowercase-file-hash + NUL.
  3. SHA-256 the combined manifest.
  4. Use the first 16 hexadecimal characters as the cache directory.

Result:

Full bundle hash:
d0097be4feba73d0db11f8fd4e1a60ee2640204a0c07044c6fdea98f7cd8f287

Expected runtime directory:
%LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0

That directory did not exist at the time of failure.

This resolved an important apparent contradiction: the application could know d0097be4feba73d0 even though it could not copy the files. Hash calculation reads source bytes; relocation happens afterward.

Step 7 — Find the exact failing relocation operation

Desktop diagnostics were searched for the event name found in the packaged program logic. Repeated records identified:

event=bundled_executable_relocation_failed
operation=copy_file
errorCode=UNKNOWN
errno=-4094
syscall=copyfile
failedExecutableName=codex.exe
source=...\WindowsApps\...\app\resources\codex.exe
destination=...\OpenAI\Codex\bin\.staging-d009...\codex.exe

The failure was no longer merely “somewhere in JP/BP/rF.” It was the first copy_file inside rF.

Step 8 — Separate source problems from destination problems

The cache destination was tested in isolation for:

  • directory creation;
  • normal file writes;
  • readback;
  • staging-directory creation;
  • same-volume rename;
  • cleanup.

All passed. No matching Microsoft Defender detection was found, and Controlled Folder Access was disabled in the tested environment.

The package source files were then inspected:

Get-Item $codex |
  Select-Object FullName, Length, CreationTime, LastWriteTime, Attributes

Get-AuthenticodeSignature $codex |
  Select-Object Status, StatusMessage

codex.exe existed, had an OpenAI signature with status Valid, and showed Encrypted. cipher /c described it as Application Protected.

A CopyFile-style copy reproduced the native Windows failure:

0x80071770: The specified file could not be encrypted.

A byte-stream copy—open source for reading, create a fresh normal destination file, copy bytes—succeeded. The destination had:

  • identical length;
  • identical SHA-256;
  • a valid OpenAI Authenticode signature;
  • no inherited Application Protected filesystem attribute.

This is the decisive root-cause experiment.

The evidence supports this precise wording:

The Desktop build's CopyFile-style relocation is incompatible with the Application Protected/encryption semantics of the installed package file. Byte-only copying succeeds and preserves the signed executable content.

It would be an overstatement to claim that OpenAI intentionally designed the cache copy to preserve this security attribute. The observable fact is that the chosen file-copy operation encounters that protection metadata and fails, whereas a fresh byte-stream destination does not.

Step 9 — Repair and independently verify the default bundled path

The final operation was not performed by the Desktop process that would later be closed. A separate PowerShell watchdog recorded time, stages, errors, processes, cache changes, hashes, and signatures to disk.

The repair sequence was:

Read current four package files
          ↓
byte-stream copy into unique staging directory
          ↓
verify four sizes + SHA-256 + Authenticode signatures
          ↓
rename staging atomically to d0097be4feba73d0
          ↓
verify final directory again
          ↓
direct smoke test: codex-cli 0.150.0-alpha.8
          ↓
start Desktop with CODEX_CLI_PATH absent
using OpenAI.Codex_2p2nqsd0c76g0!App
          ↓
inspect actual child-process executable path

The final CLI path was:

C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\d0097be4feba73d0\codex.exe

The standalone 0.149.1 installation remained on disk but was not used in this clean verification.

4. Root cause

Direct cause

rF failed during copy_file while relocating codex.exe from the MSIX package resources to the per-user runtime cache. The ordinary copy path reproduced Windows error 0x80071770; the source was Application Protected.

Why the UI said “Unable to locate”

The high-level resolver treats failed preparation as “no usable executable path.” When that resolver returns null, Desktop throws the generic locating error. Therefore “locate” includes more than searching for a filename; it includes preparing and validating a runnable cached copy.

Why August 4 had worked

The August 4 cache contained a different older four-file bundle. It demonstrates that an earlier application/bundle combination successfully populated a cache. It does not prove that build 26.820.7780.0 can copy the new package files.

The evidence does not identify the exact upstream code change that introduced the regression. It establishes that the current package content/protection state plus the current relocation copy primitive fail together.

5. Bundle identity for this exact package

| File | Bytes | SHA-256 |
|---|---:|---|
| codex.exe | 307,568,432 | 09d6723925e724edf0bbbbc7b9e204526e0fb1462c86bd2a4997311fd5071eba |
| codex-code-mode-host.exe | 65,880,368 | 3b93fc5df0b38358d7fffb290a3f11a56cecbebbf70eb62bf8c58d6d994b28e3 |
| codex-windows-sandbox-setup.exe | 15,403,312 | e5852603d0b0cf5f232efc5d6cd28b61c7f7d67e8ad4dc57314ae33190bef171 |
| codex-command-runner.exe | 8,162,096 | 955dfc76159805fffa3811a3873945a63759e92010dd30dc8b74a3a2cbfda1cc |

These values belong only to OpenAI.Codex_26.820.7780.0_x64__2p2nqsd0c76g0. They must not be reused after an application update.

6. Recovery option A: standalone CLI override

This is the lower-risk workaround for most affected users.

Install a trusted native Windows Codex CLI, record any existing value, and point the user-level override to the real codex.exe:

$oldValue = [Environment]::GetEnvironmentVariable('CODEX_CLI_PATH', 'User')

[Environment]::SetEnvironmentVariable(
  'CODEX_CLI_PATH',
  'C:\Users\<user>\.codex\packages\standalone\releases\<version>\bin\codex.exe',
  'User'
)

Completely exit and reopen Desktop.

What it changes:

Desktop
  └─ no longer depends on bundled hash/cache relocation
     └─ directly starts the explicit standalone executable

What it does not change:

  • the Desktop MSIX package;
  • WindowsApps permissions;
  • the bundled files;
  • the upstream relocation bug.

To restore the previous value later, set the saved value again. If there was no previous value:

[Environment]::SetEnvironmentVariable('CODEX_CLI_PATH', $null, 'User')

Do not clear an organization-managed value without checking its source.

7. Recovery option B: rebuild the current bundle cache by byte stream

This is an advanced, version-specific recovery for users who understand the integrity checks and want Desktop to use its bundled CLI.

The accompanying inspect-or-repair-bundled-cli.ps1 script defaults to inspection only:

powershell -ExecutionPolicy Bypass -File .\inspect-or-repair-bundled-cli.ps1

It reports:

  • the registered package and resources path;
  • the four source file sizes, hashes, and signatures;
  • the calculated full bundle hash and expected cache directory;
  • whether the cache already exists and matches;
  • user-level and current-process CODEX_CLI_PATH values.

If Get-AppxPackage is unavailable in a restricted shell, supply the exact previously verified path:

powershell -ExecutionPolicy Bypass -File .\inspect-or-repair-bundled-cli.ps1 `
  -PackageInstallLocation 'C:\Program Files\WindowsApps\OpenAI.Codex_<exact-package-name>'

After reviewing the script and output, fully exit Desktop and explicitly request repair:

powershell -ExecutionPolicy Bypass -File .\inspect-or-repair-bundled-cli.ps1 -Repair

Repair mode:

  1. refuses to run while ChatGPT/Codex Desktop processes are present;
  2. refuses to delete or overwrite an existing mismatched expected directory;
  3. creates a unique staging directory under the normal cache root;
  4. opens each signed package file for reading and creates a fresh destination file;
  5. copies bytes without attempting to carry the package filesystem protection attribute;
  6. verifies length, SHA-256, and Authenticode status;
  7. renames staging to the calculated 16-character bundle directory;
  8. verifies the final directory again.

It does not modify WindowsApps, app.asar, environment variables, or old cache directories.

8. What “reuse an already-valid bundle-hash cache” means

This phrase is easy to misread.

It does mean:

The manually created d009... directory contains exactly
the bytes expected from the current signed package.
Desktop validates it and starts its bundled CLI from there.

It does not mean:

Desktop retried its original CopyFile relocation
and successfully created d009... by itself.

The restored launch follows the default no-override resolver, but takes its “valid cache already exists” branch. The broken “cache missing → copy from WindowsApps” branch is skipped.

9. What was ruled out

  • Missing package executables
  • Invalid OpenAI Authenticode signature
  • Wrong active Desktop package or executable path
  • Start-menu/AppID/MSIX activation failure
  • Failure after Codex CLI had already started
  • General inability of Desktop to communicate with any Codex CLI
  • Cache-root ACL, create, write, read, or rename failure
  • Current bundle hash calculation failure
  • Accidental reuse of the old d7e8094cfb76a267 bundle
  • Continued use of standalone 0.149.1 in the final clean test

10. Suggested upstream changes

The relocation implementation should use a copy strategy compatible with Application Protected package payloads. Based on the successful experiment, a robust sequence would be:

  1. Open each source file read-only.
  2. Create a new ordinary destination file.
  3. Copy bytes and close/flush both streams.
  4. Validate exact size and cryptographic hash against the package source.
  5. Optionally validate the expected Authenticode publisher.
  6. Stage all files in a unique directory.
  7. Atomically rename only after the complete bundle passes validation.
  8. Remove only that incomplete staging directory on failure.
  9. Preserve older valid hash caches.
  10. Log the native Windows error code and message, not only Node/libuv UNKNOWN -4094.

Trust in the runtime cache should come from verified content identity. This recommendation is an inference from the local evidence, not a statement of OpenAI's unpublished security design.

11. Safety boundaries

  • Do not take ownership of or modify C:\Program Files\WindowsApps.
  • Do not patch app.asar.
  • Do not replace package executables.
  • Do not rename an old cache directory to a new hash.
  • Do not download these four executables from another user.
  • Do not assume the hard-coded hashes in this report apply to another Desktop build.
  • Record environment-variable values before changing them.
  • Expect a future application update to produce another bundle hash; the copy bug can recur until fixed upstream.

12. Final status

The tested machine is currently functional through the bundled default resolver with CODEX_CLI_PATH absent. The actual CLI process came from:

%LOCALAPPDATA%\OpenAI\Codex\bin\d0097be4feba73d0\codex.exe

The user-visible failure is recovered. The upstream regression is not proven fixed.

References

zhongwater123 · 20 hours ago

Additional reproduction / diagnostics on 26.820.9563.0 (Windows x64).

I hit the same startup failure pattern, with a few extra observations that may help narrow the failure path.

Before recovery

  • Package version remained OpenAI.Codex 26.820.9563.0.
  • Multiple ChatGPT.exe processes stayed alive and responsive, but all had MainWindowHandle = 0.
  • Process tree contained:
  • main process
  • --type=crashpad-handler
  • --type=gpu-process
  • --type=utility --utility-sub-type=network.mojom.NetworkService
  • --type=utility --utility-sub-type=storage.mojom.StorageService
  • There was no renderer process at that point.
  • The newest desktop log contained only a single line: Launching app.
  • No relevant Application Error, Windows Error Reporting, or Application Hang events were recorded.
  • No Crashpad .dmp files were generated in the usual Codex Crashpad report locations.

The bundled CLI was present at:

C:\Program Files\WindowsApps\OpenAI.Codex_26.820.9563.0_x64__2p2nqsd0c76g0\app\resources\codex.exe

Its properties were:

size       = 307568432 bytes
attributes = Archive, Encrypted
sha256     = 799FF77125C47B0736CEB36E9B33975BB93D4162BCA663730F3A4C90FAF2ADD9

A direct copy test to %TEMP% failed reproducibly with:

System.IO.IOException: The specified file could not be encrypted.

Recovery / workaround evidence

I also have a globally installed npm Codex CLI. The native binary is located under:

%APPDATA%\npm\node_modules\@openai\codex\node_modules\@openai\codex-win32-x64\vendor\x86_64-pc-windows-msvc\bin\codex.exe

Its properties are:

version    = codex-cli 0.150.1
size       = 310356272 bytes
attributes = Archive
sha256     = CBD657DDFE151D1A6EBAD660BEFFDBD3265DC5AFF4B3A6095124D3E2F0156F2F

Correction to my earlier wording: I initially believed no explicit CLI override was present, but a later scope check showed that CODEX_CLI_PATH is in fact set at both Process and User scope and points to the npm native binary; Machine scope is empty.

Process CODEX_CLI_PATH = %APPDATA%\npm\...\codex.exe
User    CODEX_CLI_PATH = %APPDATA%\npm\...\codex.exe
Machine CODEX_CLI_PATH = <empty>

After recovery, the desktop process tree shows its app-server child being launched from that npm-installed native Codex binary, e.g.:

%APPDATA%\npm\...\codex.exe -c features.code_mode_host=true app-server ...

At the same time, a per-user cached CLI appeared at:

%LOCALAPPDATA%\OpenAI\Codex\bin\d5f4c71927a04589\codex.exe

That cached file has:

size       = 307568432 bytes
attributes = Archive
sha256     = 799FF77125C47B0736CEB36E9B33975BB93D4162BCA663730F3A4C90FAF2ADD9
created    = 2026-08-27 22:32:07 local time

So the cached per-user file is byte-for-byte identical to the bundled resources\codex.exe (same size and SHA-256), but it is not marked Encrypted.

This is potentially useful because:

  1. a normal Copy-Item of the Application Protected / Encrypted WindowsApps binary fails with The specified file could not be encrypted;
  2. nevertheless, an identical plain cached copy eventually exists under %LOCALAPPDATA%\OpenAI\Codex\bin\...;
  3. the recovered desktop instance is using the npm native CLI via CODEX_CLI_PATH for app-server, and the renderer/main window is then created successfully.

I therefore cannot attribute recovery to running codex.exe --version; that happened around the same time, but the explicit CODEX_CLI_PATH override is the stronger explanation for why app-server successfully started. The useful findings are:

  • the 26.820.9563.0 bundled codex.exe is still Application Protected / Encrypted;
  • ordinary relocation/copy still reproduces ERROR_ENCRYPTION_FAILED behavior;
  • an explicit native CLI override provides a viable escape hatch for desktop startup;
  • the product also produced a plain per-user cached copy that is hash-identical to the protected bundled binary, suggesting there is at least one code path capable of materializing the contents without preserving the problematic encryption attribute.

It may be worth investigating both paths:

  • on relocation failure with ERROR_ENCRYPTION_FAILED, explicitly fall back to an already available native codex.exe (for example via CODEX_CLI_PATH / PATH discovery) instead of stalling before renderer creation;
  • identify which existing code path successfully materialized the hash-identical plain cached binary and reuse that Windows-compatible mechanism for the normal bundled relocation path.
Echo-rou · 17 hours ago

I can independently reproduce this on Codex Desktop 26.820.9563.0 x64.

In my case, Codex launches multiple ChatGPT.exe processes, but no GUI is ever created (MainWindowHandle = 0 for all processes). The main process remains alive/responsive and is not suspended.

The desktop log stops immediately after:

Launching app ... platform=win32
Appshot hotkey inactive configured=true enabled=false platform=win32

There is no Crashpad dump.

I also confirmed that disabling GPU does not help, and Windows app Repair/Reset plus a fresh Codex roaming profile do not resolve the issue.

The strongest evidence appears to be the bundled cua_node runtime:

...\OpenAI.Codex_26.820.9563.0_x64__2p2nqsd0c76g0\app\resources\cua_node

PowerShell reports its attributes as:

Directory, Archive, Encrypted

A direct Copy-Item test from that WindowsApps directory to a normal user-writable temp directory fails with:

The specified file could not be encrypted.

Each attempted Codex launch leaves another:

%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\.staging-*

directory behind.

I currently have many abandoned .staging-* directories from repeated startup attempts.

Interestingly, codex.exe itself was successfully relocated to:

%LOCALAPPDATA%\OpenAI\Codex\bin\d5f4c71927a04589\codex.exe

so on this machine the startup blocker appears to be specifically the cua_node runtime relocation from the Application Protected / Encrypted WindowsApps package.

This appears closely related to #34764, but in 26.820.9563.0 the failure prevents the entire Codex Desktop GUI from starting rather than only disabling Computer Use.

Happy to provide additional PowerShell diagnostics or logs if useful.

bherreraicon · 13 hours ago

Confirmed workaround on Windows 11 for the Unable to locate the Codex CLI binary regression.

Environment:

  • OpenAI.Codex 26.820.10647.0
  • Windows 11 build 26200
  • Native CLI found under %LOCALAPPDATA%\OpenAI\Codex\bin\...\codex.exe
  • CLI reported codex-cli 0.150.0-alpha.8

Observed behavior:

  • Desktop failed at startup with Unable to locate the Codex CLI binary.
  • %LOCALAPPDATA%\OpenAI\Codex\bin contained many .staging-* directories.
  • A non-staging hash directory containing codex.exe appeared, but during subsequent startup attempts that directory could be rotated/removed, so pointing CODEX_CLI_PATH directly at that managed hash directory was not stable.

Workaround that successfully started Codex Desktop:

# Find a working native codex.exe
$CodexSource = Get-ChildItem "$env:LOCALAPPDATA\OpenAI\Codex\bin" -Recurse -Filter "codex.exe" -ErrorAction SilentlyContinue |
    Where-Object { $_.FullName -notmatch '\\.staging-' } |
    Select-Object -First 1 -ExpandProperty FullName

# Verify it works
& $CodexSource --version

# Copy it outside the updater-managed Codex\bin tree
New-Item -ItemType Directory -Force "$env:LOCALAPPDATA\OpenAI\CodexCLI" | Out-Null
Copy-Item $CodexSource "$env:LOCALAPPDATA\OpenAI\CodexCLI\codex.exe" -Force

# Verify the stable copy
& "$env:LOCALAPPDATA\OpenAI\CodexCLI\codex.exe" --version

# Persist the path for the Desktop app
[Environment]::SetEnvironmentVariable(
    "CODEX_CLI_PATH",
    "$env:LOCALAPPDATA\OpenAI\CodexCLI\codex.exe",
    "User"
)

Then fully close ChatGPT/Codex processes and reopen Codex normally from Start.

This worked for me. Copying the executable outside %LOCALAPPDATA%\OpenAI\Codex\bin was important because the hash directory inside that tree was modified/removed by subsequent startup/update attempts. This is only a temporary workaround until the relocation/updater issue is fixed; the copied CLI can become stale after future updates.

ZzXxYy1234 · 5 hours ago

Also reproduces on the two builds after the one reported here, with new root-cause detail and a reliable workaround.

Versions: 26.820.9563.0 and 26.825.3734.0 (Store auto-update), Windows 11 10.0.26200 x64

Symptom variant (headless window): processes spawn but no window is ever created; the main process busy-spins (58+ CPU-seconds) for ~8 minutes; the desktop log stops right after Appshot hotkey inactive. During this state the app repeatedly creates .staging-<hash>-* directories under %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\ that stall at ~3600/4680 files, get cleaned up, and are recreated — matching bundled_executable_relocation_failed ... errno=-4094 code=UNKNOWN syscall=copyfile in the log. On 26.820.9563.0 the loop eventually succeeded and the window appeared (startupElapsedMs≈15600); on 26.825.3734.0 it did not recover on its own within 40+ minutes.

Two independent failure modes in the relocation step:

  1. EFS-encrypted package resources (see also #38696): every file under C:\Program Files\WindowsApps\OpenAI.Codex_<ver>_x64__2p2nqsd0c76g0\app\resources carries the NTFS Encrypted attribute on affected machines ((Get-Item ...).AttributesArchive, Encrypted). On accounts where EFS cannot initialize (cipher /k → "The request is not supported"), CopyFileW-based copies fail with ERROR_ENCRYPTION_FAILED ("cannot encrypt the specified file") because CopyFileW preserves the Encrypted attribute on the destination. robocopy fails the same way; plain read→write copies of the same files succeed.
  2. Paths > MAX_PATH: resources\cua_node contains pnpm-store directory trees deeper than 260 characters; with LongPathsEnabled=0 even Get-ChildItem -Recurse errors on them, so the relocation copy cannot enumerate the full tree.

Workaround that reliably unblocks startup (~15 s): pre-create the relocation destination so the app skips its own copy:

  • <hash> = the hash from the leftover %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\.staging-<hash>-* directory name (e.g. 759ccb73c5d75f83 for 26.825.3734.0);
  • stream-copy ...\app\resources\cua_node%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\<hash>\ with anything that does not preserve attributes (e.g. Node fs.readFileSync/fs.writeFileSync — 4680 files / ~319 MB, 0 failures);
  • kill ChatGPT.exe and relaunch.

(For the earlier "Unable to locate the Codex CLI binary" dialog variant on .7780: setting CODEX_CLI_PATH to a real codex.exe worked — note that pointing it at the npm codex.cmd shim fails with spawn EINVAL.)

Suggestions:

  • strip the Encrypted attribute from packaged resources, or document why Store-delivered packages end up EFS-encrypted on some machines;
  • use \\?\-prefixed (long-path-aware) paths in the relocation routine;
  • treat relocation failure as non-fatal with bounded retries and a visible error — falling back to executing the bundled binaries directly from the package path would dodge both failure modes.