Codex uses bundled pnpm instead of host toolchain

Open 💬 20 comments Opened Jun 28, 2026 by kkaatii

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

26.623.42026

What subscription do you have?

Pro

What platform is your computer?

Darwin 24.6.0 arm64 arm

What issue are you seeing?

Codex is consistently failing to run my build script because that script invokes pnpm install.

As per its own diagnosis:

  • My local projects uses PNPM v10
  • Codex comes bundled with PNPM v11 in ~/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin/pnpm
  • When running the build script, Codex uses the bundled one, leading to failure to resolve dependencies, whereas the build script is run fine in any local terminal

What steps can reproduce the bug?

  1. Create a pnpm v10 project with dependencies in package.json
  2. Run pnpm install in terminal to install the dependencies
  3. Create a js script

```javascript
import { spawn } from "node:child_process";

const child = spawn("pnpm", ["install"], {
cwd: process.cwd(),
stdio: ["ignore", "pipe", "pipe"],
});

child.on("close", (code) => {
process.exit(code ?? 1);
});
```

  1. Ask Codex (with pnpm v11 bundled) to run node script.mjs inside project dir

What is the expected behavior?

Codex should use my local pnpm binary, and ask for permission elevation when needed.

In fact, using this to run the build script is fine: PATH="path-to-my-local-nodejs/bin:$PATH" CI=true node script.mjs

Additional information

_No response_

View original on GitHub ↗

20 Comments

zhuscat · 21 days ago

I encountered the same problem in Codex Desktop App

cubicj · 21 days ago

I am seeing the same issue on Windows Codex Desktop.

Codex App: 26.623.8305.0
OS: Windows 11 Education x64, 10.0.26200
Project packageManager: pnpm@10.34.1
User-global pnpm: 10.34.1
Bundled Codex pnpm: 11.7.0

Inside Codex, Get-Command pnpm -All resolves the bundled runtime first:

C:\Users\<user>\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\pnpm.cmd
C:\Users\<user>\AppData\Roaming\npm\pnpm.ps1
C:\Users\<user>\AppData\Roaming\npm\pnpm.cmd

Running pnpm check uses the bundled pnpm and fails before the project script runs:

ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY
Aborted removal of modules directory due to no TTY

Explicitly calling the user-global pnpm works:

& "$env:APPDATA\npm\pnpm.cmd" check

This uses pnpm 10.34.1 and passes. pnpm test and pnpm build also pass with the user-global pnpm.

I opened #30541 before noticing this issue. I will close it as a duplicate, but leaving the Windows reproduction details here since the same bundled pnpm shadowing happens on Windows too.

RickVM · 21 days ago

Running into this as well on my mac, exactly the same diagnoses.

Javierg9n4 · 21 days ago

I am also running into this same issue since the last codex app update on my mac.

Alt-er · 20 days ago

how to solve

v-mec · 20 days ago

Having the same issue. As a workaround, I have told Codex to use Corepack with every pnpm command in agents.md.

I would expect turning off Configuration > Codex dependencies to fix this, but this only seems to affect Node itself.

shrinktofit · 20 days ago

same for me

shrinktofit · 20 days ago

Temp solution:

  1. add following config.toml:

``toml
[shell_environment_policy]
experimental_use_profile = true
``
This let agents spawning pwsh with your user pwsh profile

  1. run code $profile, put the following at head:
function isCodexAgentRun {
  return (($env:Path -split ';') -match '\\.cache\\codex-runtimes\\').Count -gt 0
}

# If current shell is boot by agent, source another profile profile
if (isCodexAgentRun) {
  . (Join-Path $PSScriptRoot 'CodexAgent_profile.ps1')
  return
}
  1. new a CodexAgent_profile.ps1 file in dir of $profile, with following content:
$pnpmGlobalBinDir = 'path-to-the-dir-of-your-pnpm'
$pnpmCmd = Join-Path $pnpmGlobalBinDir 'pnpm.cmd'

if (Test-Path -LiteralPath $pnpmGlobalBinDir) {
  $pathParts = $env:PATH -split ';' | Where-Object {
    $_ -and ($_.TrimEnd('\') -ine $pnpmGlobalBinDir.TrimEnd('\'))
  }
  $env:PATH = (@($pnpmGlobalBinDir) + $pathParts) -join ';'
}

function Invoke-PreferredPnpm {
  if (-not (Test-Path -LiteralPath $pnpmCmd)) {
    throw "Preferred pnpm not found: $pnpmCmd"
  }

  Write-Host "<Verbose> Invoking preferred pnpm: $pnpmCmd"

  & $pnpmCmd @args
}

function pnpm {
  Invoke-PreferredPnpm @args
}

function pnpm.cmd {
  Invoke-PreferredPnpm @args
}
mdca · 20 days ago

same

drbazzz123 · 20 days ago

Confirming this is more than a cosmetic PATH mismatch.

On our Windows Codex Desktop setup, the bundled runtime pnpm is taking precedence over the project's host toolchain and this has direct operational impact on agent-driven repo workflows.

Observed behavior in our case:

  • the project is pinned to pnpm@9.15.9
  • the Codex session resolves bundled pnpm 11.7.0 from a Codex-managed runtime path under the user's profile cache (for example: ...\.cache\codex-runtimes\...\dependencies\bin\pnpm.cmd)
  • the problematic runtime path is not present in the normal user or machine PATH; it appears in the Codex session process PATH
  • the bundled pnpm triggers unexpected install / preflight behavior instead of simply running the repo command
  • it can generate repo-visible artifacts such as placeholder pnpm-workspace.yaml
  • it interferes with validation loops, hooks, and pre-push flows

The critical point is reliability: this reduces the ability of Codex agents to autonomously and safely work through normal project loops such as:

  • run checks
  • pass repo hooks
  • commit
  • push

So from an agent-workflow perspective, this is not just a version mismatch. It is a host-vs-bundled toolchain boundary bug.

The bundled runtime for Codex-internal use is understandable. The issue is that the bundled package manager/runtime leaks into user repo command execution instead of staying isolated to Codex-internal use.

We also verified that forcing the host toolchain makes the same repo checks pass normally, which further points to session-level toolchain injection rather than a project-local configuration problem.

_This problem was investigated in depth by the agent itself, and this comment is being posted by the agent via gh on behalf of the user._
BeaconSage · 20 days ago

Codex App: 26.623.70822
macOS : 15.5
command -v pnpm: /Users/<user-name>/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin/pnpm

5kdk · 19 days ago

I’m seeing the same issue.

In my case, the project declares its pnpm version through packageManager, so I worked around it by adding this to AGENTS.md:

## Package Manager

- Before running any `pnpm` command, check the root `package.json` `packageManager` field and use that exact pnpm version.
- If the shell `pnpm` version does not match `packageManager`, use `corepack pnpm ...` from the repository root instead of the PATH-resolved `pnpm`.

This mostly keeps the agent from accidentally picking up the bundled pnpm 11 in Corepack-managed projects.

Ideally, Codex would respect the project’s intended package-manager resolution by default, whether that comes from packageManager / Corepack or the user’s local toolchain, rather than allowing the bundled pnpm to take precedence unexpectedly.

lsave · 18 days ago

encountered the same issue; even clearing .cache/codex-runtimes didn't help, as it just rebuilds itself.

goldenice · 18 days ago

I am seeing the same issue in Codex Desktop on macOS.

Additional details:

  • The “Codex dependencies” setting is disabled in the UI.
  • The local config reflects this with workspace_dependencies = false.
  • After fully restarting the Codex app, Codex still injects its bundled runtime path ahead of the user package-manager path in the agent command environment.
  • node resolves to the host nvm-managed Node, but pnpm resolves first to Codex’s bundled runtime path under ~/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin/pnpm.
  • The Codex app-server parent process already contains that runtime path in PATH, so this does not appear to come from shell startup files.
  • A clean shell without the Codex-launched environment does not include that bundled runtime path.

Expected behavior:
When “Codex dependencies” is disabled, bundled package-manager binaries should not shadow the host/project toolchain for repository commands. Bundled runtime tools may still exist for Codex internals, but they should not take precedence for user repo command execution.

michaellatman · 18 days ago

Same issue here on Codex Desktop macOS. Repo pins pnpm@10.34.4, and local nvm/corepack resolves that correctly, but Codex prepends its bundled pnpm:

~/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin/pnpm

That binary is pnpm@11.7.0, so scripts/Turbo child tasks that call plain pnpm use the bundled version instead of the repo-pinned one. In our case this caused repeated node_modules recreation attempts and ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY.

vmbehety · 18 days ago

hope this gets fixed soon, this week has been a nightmare to work with codex as my work enviroment uses pnpm 10 also

Amour1688 · 16 days ago

I hit the same root cause and have a fix branch prepared, but opening a PR is currently restricted to collaborators on this repository.

Compare link: https://github.com/openai/codex/compare/main...Amour1688:fix-runtime-path-precedence?expand=1

samthemagicman · 14 days ago

This has made Codex a complete nightmare, agreed.

christianheine · 13 days ago

Here's a workaround that worked for me (Mac):

# ~/.zshenv
export PATH="$HOME/.local/bin:$PATH"
mkdir -p ~/.local/bin
corepack enable --install-directory "$HOME/.local/bin"
corepack prepare pnpm@11.10.0 --activate

On my machine Codex finds its bundled pnpm runtime as 11.7.0. But if ~/.local/bin comes earlier, pnpm should resolve to the Corepack shim instead. Note: .zshenv is required, because ~/.zshrc is for interactive shells only. It should work ok with different pnpm versions across your repos, because corepack should resolve the correct version.

tofrankie · 12 days ago
I am using macOS.

I currently use nvm or fnm to manage Node versions, alongside a Node 22 installation via Homebrew; all of these are configured in ~/.zshrc (for interactive shells). However, the Codex App runs in a non-interactive mode, so it does not load ~/.zshrc.

My temporary workaround is to add the following conditional check to ~/.zshenv:

if [[ ! -o interactive ]] && [[ "$TERM" = dumb ]] && [[ "$PATH" == *"/Users/frankie/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin"* ]]; then
export PATH="/usr/local/opt/node@22/bin:$PATH"
fi

With this in place, executing Node-related commands (such as npm, yarn, or pnpm) will use the binary located at /usr/local/opt/node@22/bin.

[!IMPORTANT] Of course, this isn't a perfect solution, but it works for me since none of my current projects have upgraded to pnpm v11 yet.

If this approach suits your needs, you can adjust the user directory path accordingly. You can determine the correct path by running which pnpm inside the Codex App and then substituting it into the script.