openai / openai/codex

[macOS 26.818.41705] Thread resume signs out desktop — rotated refresh token never persisted to auth.json, fresh login invalidated in 76s

Open
#40,267 8 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

app auth bug session
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

On macOS, opening/resuming an existing thread signs the app out. The desktop auth poller attempts an OAuth refresh, receives 401 refresh_token_invalidated, and the UI drops to signed-out. Logging out, having auth.json removed, and signing in fresh does not fix it — a brand-new token family is invalidated within ~76 seconds.

The distinguishing detail: the rotated refresh token is never written to auth.json. After a fresh sign-in, auth.json mtime and last_refresh never advance, so the client keeps presenting a refresh token the server has already retired.

Environment

App ChatGPT.app 26.818.41705 (CFBundleVersion 6971), bundle id com.openai.codex
Bundled core codex-cli 0.149.0-alpha.4.1 (Contents/Resources/codex)
Workspace bundle 26.819.11345 (node v24.19.0, python 3.12.13), arch arm64
OS macOS (Darwin 24.6.0), Apple silicon
Auth mode chatgpt (ChatGPT sign-in, not API key)

Reproduction

  1. Sign out from the app.
  2. Confirm no ChatGPT/codex processes remain and ~/.codex/auth.json is gone.
  3. Relaunch, sign in. A new token family is written.
  4. Open any existing thread.
  5. Signed out.

Evidence

Fresh sign-in, then failure 76 seconds later:

14:39:01  sign-in; auth.json written; id_token iat 14:39:01, exp 15:39:01
14:40:17  ERROR codex_login::auth::manager
          Failed to refresh token: 401 Unauthorized
          {
            "error": {
              "message": "Your refresh token has been invalidated. Please try signing in again.",
              "type": "invalid_request_error",
              "code": "refresh_token_invalidated"
            }
          }

After that failure, ~/.codex/auth.json still holds the same refresh token written at sign-in, and last_refresh is unchanged at the sign-in timestamp. Nothing was persisted.

Every invalidation is attributed to the desktop auth poller — rpc.method="getAuthStatus" with rpc.request_id=desktop-auth:<uuid>:

caller          count
desktop-auth       12
other callers       0

Several fire in the same second as thread/resume, which is the user-visible trigger.

Error attribution by client version across full log history (token_invalidated):

bundled core 0.14x    668
desktop shell 26.818   12

Onset correlates exactly with the update. The previous desktop build (26.727.51351) last logged at 20:24:51; the new build's first log is 20:25:01, and the first refresh_token_invalidated is 20:49:05 the same evening.

Notably still working

The iOS remote client (codex_chatgpt_ios_remote) has zero auth errors in the entire log history, and successfully performed a thread/resume while the desktop was failing. Its requests ride the long-lived access_token (10-day expiry) rather than driving the hourly id_token refresh. This isolates the fault to the desktop shell's auth-refresh path rather than the account, the credentials, or the backend.

Ruled out locally

  • Not the workspace-settings 401 from #39189 — zero /backend-api/accounts/*/settings requests and zero "Must use workspace account" messages in logs.
  • Not architecture — app is arm64-only on Apple silicon, no translation involved.
  • Not filesystem/permissionsauth.json is writable, no uchg/schg flags, 173 GB free; writes succeed at sign-in and simply never happen again.
  • Not the workspace dependency bundle — intact and correctly built for arm64.
  • Not concurrent clients — 0 of 12 invalidations came from any client other than desktop-auth.
  • Not plan-related — the first failures occurred while on a paid plan.

Expected

A 401 on refresh should not drop a session whose access_token is still valid, and a successful refresh should persist the rotated token to auth.json.

Related

  • #39189 — same symptom (resume thread → sign out), different root cause, Windows
  • #36525 — refresh token reuse survives logout + deleting auth.json
  • #25443 — desktop stuck on refresh-token-revoked mid-session
  • #15754 — "refresh token was already used"

Workaround

None on the desktop. Driving Codex from the iOS remote client continues to work.

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 at the desktop auth poller handling rpc.method getAuthStatus and trace the OAuth refresh path through rotated-token persistence. Reproduce the refresh failure on macOS, then verify that successful rotations update auth.json and that a still-valid access token is not discarded on a refresh 401.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
authentication, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.