openai / openai/codex

Windows: default CODEX_HOME directory link rejects managed bundled marketplace; explicit home restores task tools

Open
#45,031 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Windows: default CODEX_HOME directory link causes reserved bundled-marketplace rejection; explicit CODEX_HOME restores task tools

Environment

  • Codex Desktop (Microsoft Store): 26.908.4834.0, Windows x64.
  • Desktop-managed Codex Core/app-server: 0.154.0-alpha.6.2.
  • PowerShell 7.6.6.
  • %USERPROFILE%\.codex is a valid directory symbolic link to an existing directory on another drive. The target is writable and has the user's existing Codex configuration.
  • Initially CODEX_HOME was unset in the Desktop startup environment.

Observed problem

Desktop startup repeatedly reports:

marketplace `openai-bundled` is reserved and cannot be added from this source

The bundled codex-app-tools plugin is not provisioned in the installed cache, and the model has no callable create_thread, read_thread, or wait_threads tools. Switching between API-provider and ChatGPT OAuth authentication did not restore these tools, including a fresh OAuth task.

This is a valid home-directory link, not a broken link, and the isolated reproduction below does not involve a proxy, model request, login credentials, or plugin execution.

Isolated Core reproduction

Use the Desktop-managed Core executable of the version above as $Codex. Run this in a disposable PowerShell process. It creates only a fresh temporary test home with an empty marketplace manifest; it does not edit the real Codex home. No cleanup/deletion commands are included.

# Set $Codex to the Desktop-managed codex.exe, not the GUI executable.
$root = Join-Path $env:TEMP ('codex-home-link-repro-' + [guid]::NewGuid().ToString('N'))
$real = Join-Path $root 'home-real'
$profile = Join-Path $root 'profile'
$alias = Join-Path $root 'home-alias'
$market = Join-Path $real '.tmp\bundled-marketplaces\openai-bundled'
$manifestDir = Join-Path $market '.agents\plugins'
New-Item -ItemType Directory -Path $manifestDir, $profile -Force | Out-Null
New-Item -ItemType Junction -Path $alias -Target $real | Out-Null
New-Item -ItemType Junction -Path (Join-Path $profile '.codex') -Target $real | Out-Null
'{"name":"openai-bundled","interface":{"displayName":"Isolated test"},"plugins":[]}' |
    Set-Content -LiteralPath (Join-Path $manifestDir 'marketplace.json') -Encoding utf8NoBOM

$savedHome = $env:HOME
$savedProfile = $env:USERPROFILE
$savedCodexHome = $env:CODEX_HOME
try {
    $env:HOME = $profile
    $env:USERPROFILE = $profile

    $env:CODEX_HOME = $alias
    & $Codex plugin marketplace add $market
    "explicit alias exit: $LASTEXITCODE"  # observed 0

    $env:CODEX_HOME = $real
    & $Codex plugin marketplace add $market
    "explicit canonical exit: $LASTEXITCODE"  # observed 0 / alreadyAdded

    Remove-Item Env:CODEX_HOME -ErrorAction SilentlyContinue
    & $Codex plugin marketplace add $market
    "default home alias exit: $LASTEXITCODE"  # observed 1 / reserved-source error
} finally {
    $env:HOME = $savedHome
    $env:USERPROFILE = $savedProfile
    $env:CODEX_HOME = $savedCodexHome
}

The distinction is implicit default home versus explicit home, not simply whether the input string contains a junction. Explicit CODEX_HOME pointing at the junction also succeeds. The marketplace source is the intended managed .tmp/bundled-marketplaces/openai-bundled location, not an arbitrary external path given a reserved name.

Desktop workaround and behavioral verification

After fully exiting Desktop, set an explicit canonical home in the parent PowerShell process and launch Desktop. Example paths below are placeholders:

$env:CODEX_HOME = 'E:\CodexHome'
$pkg = Get-AppxPackage -Name OpenAI.Codex
$exe = Join-Path $pkg.InstallLocation 'app\ChatGPT.exe'
Start-Process -FilePath $exe -WorkingDirectory (Split-Path $exe)

app\ChatGPT.exe is the GUI entrypoint verified in this installed package's manifest; assuming app\Codex.exe resulted in Access denied on this installation.

After this restart:

  • The startup log no longer contains the reserved-marketplace error and bundled-plugin reconciliation completes.
  • The codex-app-tools installed cache exists and task tools are callable in the same conversation.
  • A real OAuth create_thread call creates a projectless task; wait_threads observes completion, no error, and the exact requested marker reply (~6.8 seconds).
  • After switching back to the API provider with the same explicit-home startup, the same test succeeds again (~9.1 seconds). The child session records model_provider: custom.

The success criterion was the child's actual final marker reply, not merely obtaining a task ID. This is not a claim about every custom-provider or proxy transport configuration.

Expected behavior / investigation direction

A valid default-home link should resolve to the same trusted managed-marketplace identity as an explicit home. It should not silently prevent bundled task-tool provisioning.

Source inspection suggests inconsistent canonicalization between the local marketplace source and the expected managed root derived from the default Codex home. Relevant areas to investigate:

  • codex-rs/core-plugins/src/marketplace_add/source.rs
  • codex-rs/core-plugins/src/marketplace_policy.rs (managed root / expected-managed-path checks)

Please preserve the reserved-marketplace security boundary. A fix should normalize/resolve trusted paths consistently, not allow arbitrary sources to claim reserved marketplace names. Useful regression cases: implicit home junction, explicit junction, explicit canonical home, and rejection of unrelated/malicious reserved-name sources. The runtime reproduction is confirmed; the precise source-level repair above is an investigation direction, not a tested patch.

Related reports

  • #42783: similar missing bundled plugins / reserved-marketplace message; its directory-link cause is not established.
  • #40059: bundled-marketplace bootstrap failure; this report adds the isolated default-home link versus explicit-home comparison.
  • #39475: a broken runtime junction; this case instead has a valid Codex-home directory link and passes when the home is explicit.

No matching fix PR was found in the focused searches. No credentials, user configuration dump, session transcripts, or private filesystem paths are attached.

Contributor guide

Open the contributing guide

First steps

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

Research direction

Start with codex-rs/core-plugins/src/marketplace_add/source.rs and codex-rs/core-plugins/src/marketplace_policy.rs, then run the isolated PowerShell reproduction against the Desktop-managed Core executable. Compare implicit default-home junction, explicit junction, explicit canonical home, and unrelated reserved-name sources; done means trusted paths behave consistently while malicious reserved sources remain rejected.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell, rust
Domain
security, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.