Windows Desktop: fresh ChatGPT refresh token is rejected as refresh_token_invalidated on its first isolated refresh, causing false logout after unrelated 401
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.818.3698.0
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Windows 11 x64
What issue are you seeing?
Codex Desktop repeatedly returns to the ChatGPT login screen even though the current OAuth access token is still valid.
The account is confirmed to be a ChatGPT Plus personal account:
/backend-api/wham/accounts/checkreturns HTTP 200plan_type = plusstructure = personal- local Codex app-server
account/readreturnsplanType = plus
The reproducible failure chain in the Desktop logs is:
-
Desktop starts in a valid authenticated state:
authenticatedAccountPresent=true -
Desktop sends:
GET /backend-api/accounts/{account_id}/settings -
That request returns HTTP 401 while:
hadToken=true
tokenSource=cached -
The generic auth wrapper treats the 401 as an authentication failure and forces:
refreshToken=true -
The refresh fails and app-server reports:
authMethod=chatgpt
hasToken=false
nullReason=auth_token_missing -
Account lookup then becomes:
authenticatedAccountPresent=false
failureType=account_info_token_unavailable -
Desktop returns to the ChatGPT login screen.
However, after Desktop has already returned to the login screen, the same access token stored in ~/.codex/auth.json still successfully authenticates against:
GET /backend-api/wham/usage
and returns HTTP 200.
Therefore this appears to be a false/in-memory logout rather than an actual access-token expiration.
An earlier occurrence of the /accounts/{account_id}/settings 401 returned:
Must use workspace account for this operation
even though the account is confirmed as plus / personal.
I also performed a strict isolated refresh-token test. After a completely fresh ChatGPT login, with Desktop closed, zero other Codex processes running, exactly one app-server process, and exactly one refresh attempt, the newly issued refresh token was rejected with:
refresh_token_invalidated
The first isolated refresh returned no auth token, last_refresh did not update, and the refresh token did not rotate.
So signing out and signing back in does not resolve the issue.
What steps can reproduce the bug?
-
Sign in to Codex Desktop using a ChatGPT Plus personal account.
-
Confirm the account is initially authenticated and usable.
-
Use the Desktop app normally or wait after startup.
-
Desktop eventually sends:
GET /backend-api/accounts/{account_id}/settings -
The request returns HTTP 401 while the cached access token is still present.
-
Desktop automatically forces an authentication refresh.
-
The refresh path returns no auth token and the logs show:
auth_token_missing -
Desktop then returns to the "Log in to ChatGPT" screen.
-
Without logging in again, read the existing access token from
~/.codex/auth.jsonand use it against:
GET https://chatgpt.com/backend-api/wham/usage -
The request still returns HTTP 200, demonstrating that the access token is valid while Desktop considers the account logged out.
I also reproduced the refresh-token failure independently:
- Fully close Desktop.
- Confirm zero ChatGPT/Codex processes are running.
- Perform a fresh official ChatGPT login using Codex.
- Confirm a newly issued refresh token exists.
- Start exactly one Codex app-server.
- Perform exactly one refresh request.
- The first refresh fails with:
refresh_token_invalidated
No second app-server or Desktop process is running during this isolation test.
What is the expected behavior?
For a ChatGPT Plus personal account:
-
Desktop should not request workspace-only account settings unless the account actually supports that endpoint.
-
If
/accounts/{account_id}/settingsreturns 401 because the endpoint is unavailable for a personal account, that error should be isolated to that feature/query and should not invalidate the entire ChatGPT session. -
A still-valid cached access token should not be discarded merely because an unrelated authenticated endpoint returned HTTP 401.
-
If token refresh fails while the current access token is still valid, Desktop should continue using the valid access token instead of immediately transitioning to
auth_token_missing. -
A newly issued refresh token should be usable for its first legitimate refresh attempt.
-
Desktop should remain signed in and usable instead of returning to the login screen.
Additional information
Additional diagnostics already performed:
- Account backend classification: Plus / personal
- Local app-server classification: Plus
- Existing access token remains valid after the UI logout (
/wham/usage= HTTP 200) - Fresh login does not resolve the problem
- Cross-process refresh race was ruled out with a strict single-process isolation test
- Proxy/network connectivity is working normally
- Recreating the local Codex state did not resolve the issue
- The problem reproduces with newly created Work sessions, so it is not specific to an old conversation
I can provide sanitized Desktop logs if needed.
For privacy/security, access tokens, refresh tokens, account IDs, user IDs, and email addresses have been omitted.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the generic auth wrapper around GET /backend-api/accounts/{account_id}/settings and the app-server refresh path, using the Desktop logs and ~/.codex/auth.json behavior described here. Reproduce the isolated refresh failure and the still-valid /backend-api/wham/usage token, then verify that a personal account remains signed in when the settings request or refresh fails.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, authentication, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100