Repository navigation
[Bug]: pnpm-global Codex update installs nothing because @latest resolves under pnpm's minimumReleaseAge #14249
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Install Codex globally with pnpm 11 or later using the default
minimumReleaseAge(pnpm add -g @openai/codex) - Wait for a new
@openai/codexrelease on npm, then open T3 Code less than a day after it was published - T3 Code reports a Codex update (for me 0.158.0 to 0.159.0, published 2026-09-29 08:14 UTC)
- Press update in the app. It reports success, but the update prompt stays
- Run the copyable command
pnpm add -g @openai/codex@latest. pnpm installs 0.158.0 again. Runningpnpm add -g @openai/codex@0.159.0instead installs 0.159.0
Expected behavior
Pressing update installs the version T3 Code advertises, or T3 Code does not advertise a version pnpm will not install yet
Two options, depending on whether T3 Code should respect pnpm's release-age setting:
- Pin pnpm-global updates to the advertised version. pnpm then installs it and records the package in
minimumReleaseAgeExclude, which bypasses the delay for that version - Keep
@latestbut compare against the newest version older thanminimumReleaseAge, so no update is offered until pnpm would install it
Actual behavior
Every update run ends in success, but Codex stays on 0.158.0 and the update prompt stays. There is no error message
pnpm resolves @openai/codex@latest to the newest version older than minimumReleaseAge and exits successfully without mentioning the skipped release. The in-app update and the copyable command both use @latest, so neither T3 Code nor the user learns why nothing changed
T3 Code takes latestVersion from the npm registry's latest tag with no release-age check. makeTargetedProviderUpdateAction in apps/server/src/provider/providerMaintenance.ts can already pin a version, but the pnpm-global update used @latest. This is unchanged on current main and nightly
Impact
Minor bug or occasional failure
Version or commit
v0.0.43-nightly.20260929.2416 @ b21f3b7
Environment
Windows 11 Pro 10.0.26200, T3 Code Nightly desktop, Node 24.21.0, pnpm 12.6.0 (no minimum-release-age override set), Codex CLI 0.158.0 installed with pnpm at %LOCALAPPDATA%\pnpm\bin\codex
Logs or stack traces
Manual run of the copyable command (npm `latest` tag is 0.159.0, published 2026-09-29 08:14 UTC):
$ pnpm add -g @openai/codex@latest
Packages are hard linked from the content-addressable store to the virtual store.
Content-addressable store is at: %LOCALAPPDATA%\pnpm\store\v11
Virtual store is at: AppData/Local/pnpm/global/v11/<hash>/node_modules/.pnpm
.../global/v11/<hash> | Progress: resolved 2, reused 2, downloaded 0, added 2, done
dependencies:
+ @openai/codex 0.158.0
Done in 403ms using pnpm v12.6.0
Same machine, isolated fresh pnpm home, global installs:
$ pnpm add -g @openai/codex@latest -> + @openai/codex 0.158.0
$ pnpm add -g @openai/codex@0.159.0 -> + @openai/codex 0.159.0
and the global package's pnpm-workspace.yaml gains:
minimumReleaseAgeExclude:
- '@openai/codex@0.159.0-darwin-arm64 || 0.159.0-darwin-x64 || 0.159.0-linux-arm64 || 0.159.0-linux-x64 || 0.159.0-win32-arm64 || 0.159.0-win32-x64 || 0.159.0'
Server trace (local time), three in-app update presses:
11:33:46 ws.rpc.server.updateProvider 5547ms Success
ProviderMaintenanceRunner.runCommand 3751ms Success
11:33:59 ws.rpc.server.updateProvider 1543ms Success
ProviderMaintenanceRunner.runCommand 549ms Success
11:34:15 ws.rpc.server.updateProvider 1719ms Success
ProviderMaintenanceRunner.runCommand 524ms Success
Cached Codex provider status after the runs:
"updateCommand":"pnpm add -g @openai/codex@latest"
"currentVersion":"0.158.0"
"latestVersion":"0.159.0"
"status":"behind_latest"Screenshots, recordings, or supporting files
No response
Workaround
Wait until the release is older than minimumReleaseAge, or run pnpm add -g @openai/codex@<version>, which installs it and adds a minimumReleaseAgeExclude entry
Activity
[-][Bug]: pnpm-global Codex update silently does nothing while the new release is inside pnpm's minimum release age[/-][+][Bug]: pnpm-global Codex update installs nothing because `@latest` resolves under pnpm's minimumReleaseAge[/+]juliusmarminge commentedon Sep 29, 2026
Triage
Confirmed on current main. Not a duplicate.
The pnpm-global update is
pnpm add -g <package>@latest(resolvePackageManagedProviderMaintenanceinapps/server/src/provider/providerMaintenance.ts). The advertised version is the npmlatestdist-tag (fetchNpmLatestVersionrequestsregistry.npmjs.org/<package>/latest) with no release-age check. That tag is0.159.0for@openai/codexright now.pnpm 11+ defaults
minimumReleaseAgeto 1440 minutes. With no override, that default is non-strict, so@latestresolves to the newest version old enough to pass and the command exits 0 without mentioning the skipped release. That matches this report:updateProviderandrunCommandsucceed because pnpm exited 0, Codex stays on 0.158.0, and the advisory staysbehind_latest, so the prompt stays.The in-app result should not be a green "Provider updated". After a zero exit,
ProviderMaintenanceRunnermarks the updateunchangedwhen the refreshed advisory is stillbehind_latest, and the toast is the warning "Provider still needs an update". pnpm is the part that prints no reason.The ordinary Update button does not pin a version.
makeTargetedProviderUpdateActioncan rewrite apnpm-global@latestargument to an exact version, but that only runs whentargetVersionis set (the compatibility "install recommended" action). The copyable command is the same@lateststring, so running it by hand does the same thing.This is every provider installed as a pnpm global, not only Codex. npm and bun also update with
@latest, but they do not have this default age gate. Homebrew already avoids the same mismatch by takinglatestVersionfrombrew infoinstead of npm.Closed PR #8363 was about a different pnpm-global failure (install scripts skipped while the command still exits 0). It did not cover release age.
Both fixes in the report fit the code that is already there:
minimumReleaseAgeExclude. That bypasses the default cooldown for that version. pnpm's older crash on immature exact global installs (pnpm add -g crashes with unhandled resolution-policy violations when minimumReleaseAge blocks an exact global install pnpm/pnpm#11748) was fixed.@latestand only advertise the newest version pnpm would actually install, the same way Homebrew compares against whatbrew upgradecan deliver.No further info needed.
Neonsy commentedon Oct 5, 2026
Wanted to note that I just saw the manual suggestion command on the currently latest nightly to be:
but that causes the same skip
HerbCaudill commentedon Oct 10, 2026
Same issue here.
A workaround is to exclude Codex from pnpm's release-age wait:
This adds the following to your global pnpm config (
~/Library/Preferences/pnpm/config.yamlon macOS):After that,
pnpm add -g @openai/codex@latestinstalls the newest release right away, and T3's update button works. The tradeoff is that you lose the one-day buffer for Codex. Every other package keeps it.If you already have entries in
minimumReleaseAgeExclude, add@openai/codexto your existing list. The command above replaces the whole list.beanow-at-crabnebula commentedon Oct 16, 2026
The workaround of
minimumReleaseAgeExcludewill of course work.However I think the preferred solution would be to respect the pnpm policy. There are far too many malware on NPM incidents to discard this very sensible measure that pnpm made the default.
I would find it rather concerning if T3code was making automatic decisions to grant exceptions for a security-sensitive policy like this too. So I don't think it should add the exception just for the UX paper cut, undermining the security model.
PNPM itself can confirm whether a provider "still needs updates".
At the time of writing,
2.1.301is the actual latest Claude release, but2.1.300is the latest that is past for the minimum age threshold.This would avoid hard-coding / guessing what the configured age is for your machine. As well as being able to respect any exceptions to the policy, including when it's a particular version range or particular package.
It looks like #19580 implements exactly that.
juliusmarminge commentedon Oct 19, 2026
Note
Grok responding on behalf of Julius.
Fixed by #14295, which just merged: pnpm-global provider updates now install the exact version T3 Code advertises instead of
@latest, in both the Update action and the copyable command. Whether updates should instead respect pnpm's release-age delay is being tracked separately in #15329. Closing as completed; it'll ship in the next nightly.