Skip to content

[Bug]: Homebrew-installed Codex/Claude flagged outdated against npm latest, brew upgrade cannot clear it #7730

Description

@ishaanko

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

  1. Install Codex with Homebrew: brew install --cask codex (same applies to brew install --cask claude-code).
  2. Wait for a Codex release to land on npm before the Homebrew cask is bumped. This happens on every release; today @openai/codex@0.149.0 hit npm at 21:04Z and the cask is still at 0.148.0.
  3. Open T3 Code. The Codex provider shows an update with the command brew upgrade codex.
  4. Run the in-app update, or brew upgrade codex in a terminal. Homebrew reports nothing to do.
  5. The advisory stays on "update available".

Expected behavior

A Homebrew-managed install is compared against what Homebrew can deliver. If the cask is at 0.148.0 and the install is 0.148.0, the provider is current, and the advisory only appears once the cask is bumped.

Actual behavior

resolveLatestProviderVersion in apps/server/src/provider/providerMaintenance.ts fetches latest from https://registry.npmjs.org/<package>/latest for every install kind, including when resolvePackageManagedProviderMaintenance has already decided the install is Homebrew-managed and the update command is brew upgrade <formula>. npm and the Homebrew cask publish at different times, so the advisory is behind_latest with an update command that cannot satisfy it. The nag persists until the cask catches up, which can be hours.

Cached provider snapshot on the affected machine (~/.t3/caches/codex.json):

"version": "0.148.0",
"versionAdvisory": {
  "status": "behind_latest",
  "currentVersion": "0.148.0",
  "latestVersion": "0.149.0",
  "updateCommand": "brew upgrade codex",
  "canUpdate": true
}

Impact

Major bug

Version or commit

0.0.34-nightly.20260820.1146 (desktop); the same code is on main @ fe87502

Environment

macOS 26 (Darwin 25.6.0) arm64, Node v24.18.0, codex 0.148.0 via Homebrew cask (/opt/homebrew/Caskroom/codex/0.148.0)

Logs or stack traces

$ brew info --cask codex | head -1
==> codex (Codex): 0.148.0
$ curl -s https://formulae.brew.sh/api/cask/codex.json | jq .version
"0.148.0"
$ curl -s https://registry.npmjs.org/@openai%2Fcodex/latest | jq .version
"0.149.0"

Workaround

Turn off provider update checks in Settings, or wait for the cask to be bumped.

Related

Found by investigating the machine with a coding agent (Claude Fable 5 in Claude Code), alongside t3 triage machine facts.

Activity

  1. mchisolm0 commented on Sep 3, 2026

    @mchisolm0

    Still reproducing on 0.0.38 (desktop, macOS 26 / Darwin 27.0.0 arm64, Node v24.19.0), 13 days after this was filed. Adding fresh evidence plus a three-machine spread that shows how the npm-latest comparison behaves across install channels.

    Same failure, current versions

    $ codex --version
    codex-cli 0.152.1
    $ brew info --cask codex | head -1
    ==> codex (Codex): 0.152.1
    $ brew outdated --cask codex
    (nothing)
    $ curl -s https://registry.npmjs.org/@openai%2Fcodex/latest | jq -r .version
    0.153.0
    

    The cask is at parity with what Homebrew can deliver, so brew upgrade codex is a correct no-op, and the advisory stays behind_latest against npm's 0.153.0.

    providerMaintenanceRunner.ts classifies this as unchanged with "Update command completed, but T3 Code still detects an outdated provider version." That message reads as "the update didn't take", so the natural response is to click again. From the server trace — five attempts in 74 seconds before the user gave up and ran t3 triage:

    04:33:06  ProviderMaintenanceRunner.runCommand  12073ms
    04:33:20  ProviderMaintenanceRunner.runCommand  20472ms   <- reinstalled the same 0.152.1
    04:33:41  ProviderMaintenanceRunner.runCommand   9805ms
    04:33:59  ProviderMaintenanceRunner.runCommand    406ms
    04:34:20  ProviderMaintenanceRunner.runCommand    362ms   <- brew had nothing left to do
    

    Homebrew's own receipt confirms the second attempt did real work and still changed nothing user-visible: Installed using the internal formulae.brew.sh API on 2026-09-03 at 04:33:40.

    Claude Code hits this too, and the gap is wider

    claude-code cask:  2.1.236
    npm @anthropic-ai/claude-code: 2.1.259
    

    A second machine in the same fleet installs Claude Code via brew install --cask claude-code and has been showing an unclearable advisory at 2.1.236. 23 patch versions is well past the "a few hours" window in the original report — for Claude Code the cask lag looks structural rather than transient, so the nag is effectively permanent there, not self-healing.

    Suggested fix

    Source the latest version from the same channel that the resolved update command targets, rather than always npm:

    • Homebrew-managed -> https://formulae.brew.sh/api/cask/<token>.json (.version)
    • npm/bun/pnpm-managed -> npm registry (current behavior, correct there)
    • native-managed -> the provider's own updater already reports currency; skipping the advisory entirely would be safer than comparing against npm

    resolvePackageManagedProviderMaintenance has already decided the channel by the time resolveLatestProviderVersion runs, so the information needed is on hand — ProviderMaintenanceCapabilities would just need to carry the channel alongside packageName.

    Failing that, treating "command exited 0 but version did not move" as current for this channel rather than unchanged would at least stop the advisory from inviting an unbounded retry loop.

    Possibly a related gap (happy to split into its own issue)

    The third machine in the fleet (Linux, no Homebrew) installs Codex with the standalone installer, which uses a versioned layout plus a current symlink — structurally identical to the Claude native install that ClaudeDriver already detects:

    ~/.local/bin/codex -> ~/.codex/packages/standalone/current/bin/codex
    ~/.codex/packages/standalone/releases/
      0.142.5-x86_64-unknown-linux-musl
      0.145.0-x86_64-unknown-linux-musl
      0.147.0-x86_64-unknown-linux-musl
      0.149.1-x86_64-unknown-linux-musl
    

    CodexDriver.ts sets nativeUpdate: null, and that path matches none of the detectors in resolvePackageManagedProviderMaintenance. With the default bare-name binaryPath (settings.ts, makeBinaryPathSetting("codex")) it falls through to the npm-global fallback and runs npm install -g @openai/codex@latest. That command succeeds, but it installs a second copy into the mise-managed Node prefix, whose bin directory precedes ~/.local/bin on PATH:

    $ command -v codex
    ~/.local/share/mise/installs/node/24/bin/codex     # 0.153.0, installed by the fallback
    $ ls ~/.local/bin/codex
    ~/.local/bin/codex -> ~/.codex/packages/standalone/current/bin/codex   # still 0.149.1
    

    So the advisory clears, but the standalone tree the vendor installer owns is now orphaned at the old version, and the copy that satisfied the advisory lives inside a runtime that mise reinstalls on upgrade — at which point codex silently reverts to 0.149.1 and the advisory returns. Updating a provider by installing it into a different channel than the one it came from is the underlying issue in both halves of this report.

    Codex does ship its own updater:

    $ codex --help | grep update
      update            Update Codex to the latest version
    

    So the Claude treatment appears to port over directly:

    nativeUpdate: {
      executable: "codex",
      args: ["update"],
      lockKey: "codex-native",
      isCommandPath: (p) => normalizeCommandPath(p).includes("/.codex/packages/standalone/"),
    }

    That would fix the standalone case and also give Homebrew-cask installs a working escape hatch, since codex update is available there too — which is relevant to the main issue above, where brew upgrade provably cannot deliver the version npm is advertising.

    Environment: T3 Code 0.0.38 desktop (server on 127.0.0.1), macOS 26 (Darwin 27.0.0) arm64, Node v24.19.0, codex 0.152.1 via Homebrew cask.

    Investigated with t3 triage (Claude Opus 5 in Claude Code).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions