[Windows 26.814] Opening an existing thread signs out a personal Pro account after workspace-only settings 401
What version of the Codex App are you using (From “About Codex” dialog)?
OpenAI.Codex 26.814.5167.0 (desktop client 26.814.41407; bundled Codex core 0.148.0)
What subscription do you have?
ChatGPT Pro (personal account)
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
After updating the former Codex app to the unified ChatGPT desktop app, browser-based ChatGPT sign-in succeeds and an existing Codex conversation initially opens correctly. A few seconds later, the desktop app switches to the signed-out state and asks the user to sign in again.
The fresh access token is unexpired and is accepted by the Codex models endpoint (HTTP 200). The failure starts when the unified desktop client requests /backend-api/accounts/{account_id}/settings, which returns HTTP 401. A direct read-only verification of the same endpoint returns:
Must use workspace account for this operation
The client then calls getAuthStatus(refreshToken=true); OAuth refresh returns HTTP 401 with refresh_token_invalidated, and the UI signs out.
This report intentionally excludes access tokens, refresh tokens, email addresses, account IDs, thread IDs, and raw log archives.
What steps can reproduce the bug?
- Launch the Windows unified ChatGPT/Codex desktop app.
- Complete browser-based "Sign in with ChatGPT" using a personal ChatGPT Pro account.
- Open an existing Codex conversation.
- Wait several seconds.
- Observe that the app returns to the signed-out state.
Observed timeline after a full Windows App reset:
- OAuth token exchange succeeds with HTTP 200.
account/login/completed; a freshauth.jsonis written.- The existing thread resumes successfully (159 items, 0 parse errors).
- The Codex models endpoint returns HTTP 200 using the fresh access token.
- The desktop request to
/backend-api/accounts/{account_id}/settingsreturns HTTP 401. - The desktop client forces
getAuthStatus(refreshToken=true). - OAuth refresh returns HTTP 401 with
refresh_token_invalidated. - The desktop UI switches to signed out.
Recovery steps already attempted, with no change:
- Removed and regenerated
auth.json. - Set
cli_auth_credentials_store = "file". - Disabled and stopped third-party token-keeper/injection software.
- Fully reset the Windows App package with
Reset-AppxPackage. - Recreated package-local cache and state directories.
- Signed in from the ChatGPT surface before returning to Codex.
What is the expected behavior?
The desktop app should accept the valid personal Pro ChatGPT token and keep the user signed in. It should avoid a workspace-only account-settings request for a personal account, or handle that HTTP 401 without treating the otherwise valid Codex session as invalid.
Additional information
This is related to, but more specific than, #35673. In this case the desktop app becomes usable after OAuth and can resume the thread; the forced sign-out occurs only after the workspace-only settings request fails.
Environment details:
- Package:
OpenAI.Codex_26.814.5167.0_x64__2p2nqsd0c76g0 - Standalone Codex CLI
0.147.0works with the same account. - The stored account ID matches the access-token account claim.
- No other Codex App or CLI process issued a refresh request during the failure window.
28 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Additional A/B account comparison (sanitized)
I tested two different ChatGPT accounts on the same Windows device and the exact same installed desktop build.
/backend-api/accounts/{account_id}/settingswithMust use workspace account for this operation.hasToken=falsewithauth_token_missing; an earlier refresh attempt returnedrefresh_token_invalidated.This comparison narrows the issue: the workspace-only settings 401 is not sufficient by itself to cause sign-out. The failure appears to be account-specific and related to the refresh-token/session lifecycle triggered by the updated desktop client.
No email addresses, account IDs, access or refresh tokens, thread IDs, or raw logs are included.
Confirmed workaround: clear the ChatGPT Web multi-account session
This is now resolved on the same affected Windows installation and desktop build.
After reviewing #39199, I confirmed that the browser used for OAuth had two ChatGPT accounts active through ChatGPT Web account switching. I then:
Result:
This narrows the diagnosis: the workspace-only settings 401 may still occur, but it was not the root cause of the sign-out. In this case, the upstream trigger was the ChatGPT Web multi-account session interfering with the desktop OAuth refresh-token lifecycle.
Current workaround: sign out of all ChatGPT Web accounts in the OAuth browser, then sign in to only the account intended for Codex Desktop before starting the desktop login flow.
No email addresses, account IDs, tokens, thread IDs, or raw logs are included.
I had the same issue and your tip fixed it. I wasn’t signed in with multiple accounts, though — I only had one Pro account. Logging out of that account and then signing back into the ChatGPT app solved it for me.
Same issue on Windows — and a workaround that has held: clear the browser session you sign in with, not app state.
Setup: Windows 11, Microsoft Store package
OpenAI.Codex26.814.5167.0 (desktop client 26.814.41407), personal account.The Store auto-updated the app from 26.810.7004 to 26.814.5167 at 7:06 PM local yesterday. The previous build had run all day with zero auth errors; the first failure hit minutes after the new build registered. From the app's own log DB (
~/.codex/logs_2.sqlite, targetcodex_login::auth::manager):Also new in this build:
codex_login::auth::managerlogsReloading authroughly once per second while the loop is active (300+ entries within ~30 minutes of the update; zero occurrences anywhere in the prior 30 days of logs).Consistent with what OP reported, local resets (auth file, credential store, app package) don't help — and I think that's the tell. The sign-in flow round-trips through the default browser, so the new grant inherits whatever session context
auth.openai.comalready had there. If that browser-side session is stale, every sign-in comes back poisoned the same way, no matter how much app state you wipe.Workaround that worked here: clear the signing browser's data for the OpenAI domains (I cleared Chrome data wholesale; a targeted clear of cookies for
auth.openai.com/chatgpt.com/openai.comis likely enough), then sign in again when the app opens the browser. Result: sign-ins went from dying within a minute (44s, then 11s) to fully stable — 30+ minutes including long agent runs, with zero auth errors or logouts in the log since. The 1 HzReloading authchurn also stopped.The browser-session dependency might explain why this only hits some accounts: it seems to need a stale browser-side OpenAI session (mine dated back months) for the sign-in to inherit.
This works. 👍
I can reproduce this on Windows with the unified ChatGPT desktop app.
Environment
26.814.41957Reproduction
The same conversations work normally on
chatgpt.comin the browser and in the iPhone app.I also uninstalled and reinstalled the new desktop app, but the problem persisted.
I captured the failure using Help → Start Performance Trace.
Performance trace Feedback ID:
no-active-thread-01a01ae6-8bd2-7c60-ac75-de810f65a3bcThis appears consistent with the issue reported here: authentication succeeds initially, but opening an existing thread triggers an immediate logout.
A few additional data points after further testing:
Timeline / affected machine
Current affected installation:
26.814.41957(Released Aug 17, 2026)OpenAI.Codex 26.814.5517.0OpenAI.ChatGPT-Desktop 1.2026.190.0I also reproduced the issue after a clean Windows reboot with ChatGPT Classic disabled from startup and not running.
The issue is not limited to existing threads
I tested a completely new standalone conversation in Chat mode, outside any Project:
Importantly, I then opened
chatgpt.comin the browser and found that this newly created conversation was present there, including both my message and the complete assistant response.So the server-side conversation creation and model response appear to succeed; the desktop client logs out during or immediately after response handling.
Existing conversations still reproduce the original behavior as well: opening them causes an immediate logout.
Performance trace previously submitted:
no-active-thread-01a01ae6-8bd2-7c60-ac75-de810f65a3bcUseful negative control: another Windows installation is working normally
My wife's Windows desktop installation is currently working normally in Chat mode.
Her versions are:
26.814.41407(Released Aug 17, 2026)OpenAI.Codex 26.814.5167.0OpenAI.ChatGPT-Desktop 1.2026.190.0She is actively using Chat without this logout problem.
This seems important because
26.814.41407 / 26.814.5167.0can apparently work normally on another Windows installation/account, while my newer26.814.41957 / 26.814.5517.0installation consistently fails.So the 26.814 build alone may not be a sufficient condition; there may also be an account/session/auth-state-dependent trigger.
Confirming that this remains reproducible on a newer Windows package.
Environment
Microsoft Windows NT 10.0.26200.0 x64OpenAI.Codex 26.814.5517.0User-visible behavior
The app was already authenticated and working, then unexpectedly switched to the Sign in to ChatGPT screen.
There is an important difference between the two login paths:
This suggests that the browser association itself is healthy; the sign-in action is failing only after the desktop client enters the forced signed-out/stale auth state.
Sanitized log markers from the latest occurrence
During
2026-08-19T20:59:40Z–21:03:57Z, the current desktop process recorded:desktop_fetch_auth_401account_login_completedMust use workspace account for this operationauth_token_missingEarlier occurrences on the same installation also recorded:
Failed to refresh authentication tokenFailed to retrieve authentication tokenThe latest event therefore follows the same general sequence reported here: authentication/login completes, account-dependent desktop requests return 401, the token becomes unavailable, and the UI falls back to sign-in.
The browser-session cleanup workaround discussed in this issue has not yet been tested for this latest occurrence.
No tokens, email addresses, account IDs, thread IDs, local paths, or raw logs are included.
<html>
<body>
<!--StartFragment--><html><head></head><body><p>Confirming this on a personal (non-workspace) ChatGPT account. Same failure chain, and in my case it also happens on <strong>brand-new chats</strong>, not only when resuming an existing thread.</p>
<h3>Environment</h3>
|
-- | --
OS | Windows 11 x64
Package | OpenAI.Codex 26.814.5517.0_x64__2p2nqsd0c76g0
Desktop client release | 26.814.41957
Account type | personal ChatGPT (authMethod=chatgpt), not a workspace member
<h3>Timeline strongly points at the update</h3>
<ul>
<li>App package updated: <strong>2026-08-19 17:07</strong> (local, UTC+3)</li>
<li>First <code>desktop_fetch_auth_401</code> in the app logs: <strong>2026-08-19T14:09:12.075Z</strong> = 17:09 local</li>
</ul>
<p>Two minutes after the update. There is not a single <code>desktop_fetch_auth_401</code> entry before that point. Counts since: <strong>593</strong> occurrences on 08-19, <strong>378</strong> on 08-20.</p>
<h3>Failure chain (from <code>%LOCALAPPDATA%\Packages\OpenAI.Codex_*\LocalCache\Local\Codex\Logs</code>)</h3>
<pre><code>[devicecheck-attestation] DeviceCheck attestation unavailable deviceCheckLatencyMs=null durationMs=0 errorCode=1
[electron-fetch-wrapper] desktop_fetch_auth_401 hadToken=true skipRetryReason=null
target="GET https://chatgpt.com/backend-api/accounts/:param/settings"
tokenSource=cached willRetry=true
[AppServerConnection] app_server_connection.auth_status_result authMethod=chatgpt
hasToken=false nullReason=auth_token_missing refreshToken=true tokenExpiryState=missing
[electron-message-handler] sa_server_request_failed status=401
errorMessage="{\"detail\":\"Missing valid access token or actor biscuit\"}"
routePattern=/accounts/{account_id}/settings
[electron-fetch-wrapper] desktop_fetch_auth_401 hadToken=false skipRetryReason=no_token_attached
target="GET https://chatgpt.com/backend-api/wham/:param/:param" willRetry=false
</code></pre>
<p>After that every subsequent request goes out with no token at all (<code>hadToken=false</code>, <code>no_token_attached</code>) and the app drops to the sign-in screen.</p>
<h3>The token itself is valid — this is not an expiry problem</h3>
<p>Checked <code>~/.codex/auth.json</code> directly:</p>
<ul>
<li><code>auth_mode = chatgpt</code>, no <code>OPENAI_API_KEY</code> set</li>
<li><code>last_refresh = 2026-08-20T05:41:06Z</code> (file written successfully, so storage is writable)</li>
<li><code>access_token</code> JWT <code>exp</code> decodes to <strong>2026-08-30</strong>, i.e. still valid for 10 more days at the moment of the 401</li>
<li>File ACL is normal, <code>EnableControlledFolderAccess = 0</code>, no security software touching the file</li>
</ul>
<p>So the app discards a perfectly valid token because one workspace-only endpoint answered 401.</p>
<h3>Network is not the cause</h3>
<p>I initially suspected my connection. Verified it is fine at the moment the 401s occur:</p>
<pre><code>$ curl https://chatgpt.com/cdn-cgi/trace
h=chatgpt.com
ip=<redacted>
colo=AMS
loc=NL
tls=TLSv1.3
</code></pre>
<p>Requests to <code>chatgpt.com</code>, <code>auth.openai.com</code> and <code>ab.chatgpt.com</code> all complete normally in the network layer log at the same timestamps.</p>
<h3>What does NOT work as a workaround</h3>
<ul>
<li>Signing in again — the app signs out again within seconds</li>
<li>Starting a new chat instead of resuming an old thread</li>
<li>Reinstalling the app</li>
</ul>
<h3>Suggested fix</h3>
<p>A 401 from <code>/backend-api/accounts/{account_id}/settings</code> for a personal account should be treated as "this endpoint is not applicable to this account type" and ignored, not as proof that the session is invalid. Right now it triggers a forced refresh that destroys a working session, and the resulting state is unrecoverable without re-login — which then immediately repeats.</p></body></html><!--EndFragment-->
</body>
</html>
Confirming this on a personal (non-workspace) ChatGPT account. Same failure chain, and in my case it also happens on brand-new chats, not only when resuming an existing thread.
Environment
| | |
|---|---|
| OS | Windows 11 x64 |
| Package |
OpenAI.Codex 26.814.5517.0_x64__2p2nqsd0c76g0|| Desktop client release |
26.814.41957|| Account type | personal ChatGPT (
authMethod=chatgpt), not a workspace member |Timeline strongly points at the update
desktop_fetch_auth_401in the app logs: 2026-08-19T14:09:12.075Z = 17:09 localTwo minutes after the update. There is not a single
desktop_fetch_auth_401entry before that point. Counts since: 593 occurrences on 08-19, 378 on 08-20.Failure chain (from
%LOCALAPPDATA%\Packages\OpenAI.Codex_*\LocalCache\Local\Codex\Logs)After that every subsequent request goes out with no token at all (
hadToken=false,no_token_attached) and the app drops to the sign-in screen.The token itself is valid — this is not an expiry problem
Checked
~/.codex/auth.jsondirectly:auth_mode = chatgpt, noOPENAI_API_KEYsetlast_refresh = 2026-08-20T05:41:06Z(file written successfully, so credential storage is writable)access_tokenJWTexpdecodes to 2026-08-30, i.e. still valid for 10 more days at the moment of the 401EnableControlledFolderAccess = 0, no security software touching the fileSo the app discards a perfectly valid token because one workspace-only endpoint answered 401.
Network is not the cause
I initially suspected my connection and ruled it out. At the same timestamps as the 401s:
Requests to
chatgpt.com,auth.openai.comandab.chatgpt.comall complete normally at the network layer.What does NOT work as a workaround
Suggested fix
A 401 from
/backend-api/accounts/{account_id}/settingsfor a personal account should be treated as "this endpoint does not apply to this account type" and ignored, not as proof that the session is invalid. Right now it triggers a forced refresh that destroys a working session, and the resulting state is unrecoverable without re-login — which then immediately repeats.Confirming the same failure chain on macOS, personal (non-workspace) account, and confirming the browser-session workaround fixes it there too.
Environment
Timeline points at the update, same as the Windows reports
Same chain as OP, from ~/Library/Logs/com.openai.codex:
Data point supporting the poisoned-grant theory rather than a local race: a refresh token minted 26 seconds earlier was already refresh_token_invalidated, with every other local process that shares ~/.codex/auth.json stopped during the test. The access token from the same grant was still accepted by /backend-api/wham/tasks/list (200) at that moment. Fresh app browser profile, keychain check, and clock check (9 ms offset) changed nothing.
Workaround confirmed on macOS: quit the app, sign out of chatgpt.com in the default browser (Brave here), clear cookies for chatgpt.com / auth.openai.com / openai.com, sign back in to the single intended account, then sign in to the desktop app. Sign-in now sticks; opening existing threads works; no further desktop_fetch_auth_401 or refresh_token_invalidated entries in the logs.
Adding a code-level repro from 26.818.2441.0 because this failure mode is even worse than it looks.
The bundled client literally names the call
getWorkspaceSettings()and maps it to/accounts/{account_id}/settings. The sidebar/project gate (Orl()in this build) first looks at current account data. Ifstructure === "workspace"it uses the workspace ID, which is fine. But if current account data isnulland loading has stopped, it falls back to the auth account ID anyway and calls the workspace endpoint.That is exactly the wrong fallback during an account/login outage. With a personal Pro Lite account the route answers:
401 Must use workspace account for this operationThen
performDesktopFetch()sees any authenticated 401, forces a token refresh, and the live app state becomes:hasToken=false nullReason=auth_token_missing refreshToken=trueThe UI kicks the user out while an already-running Codex CLI task keeps working. I also reproduced the kick without opening an old thread: a live task/sidebar update was enough. So the thread is not corrupt. The sidebar permission check is detonating auth.
This is ridiculous. A check for
chatgpt.workspace.project.crudshould not be able to destroy the whole session. Please do both obvious fixes: do not call workspace settings until account structure is known to beworkspace, and do not treat a route-specific authorization 401 as proof that the OAuth session is dead. Re-login loops, cache wipes, and reinstalling are not acceptable answers for a client bug like this.No raw logs, IDs, tokens, email addresses, thread IDs, or local paths are included here.
Disclosure: I used Codex to inspect the local app logs and bundled JavaScript and to help write this comment. I reviewed the result before posting.
Confirming the workaround on Windows with a personal ChatGPT Pro account and OpenAI.Codex 26.818.2441.0. After fully quitting the desktop app, signing out of ChatGPT in the OAuth browser, clearing browser site data for the OpenAI/ChatGPT domains, signing back in to only the intended account, and then authenticating the desktop app again, the app remained signed in and existing conversations loaded normally. No reinstall or Windows App package reset was needed. This confirms the browser-session reset workaround on the current Windows package.
Impact: diagnosing and recovering from this cost me roughly 4–5 hours.
On my Macbook Air M4 Base model, I have the same issue. Also, the workaround suggested here did not provide a solution for the issue. I still cannot do any work on my paid account.
@orkasi For clarity, to fix the issue, in Chrome I went to Settings → Privacy and security → Third-party cookies → See all site data and permissions. I searched for and deleted all site data matching chatgpt.com, auth.openai.com, and openai.com. I did this after fully quitting the desktop app and signing out of ChatGPT Web. I then signed back into only the intended account before reopening the desktop app. PS I didn't clear all Chrome browsing data if they are earlier instructions.
Reproducing this on a newer build than the one originally reported, with a full network-level trace from the app's own Sentry breadcrumbs. My account is a personal account with no workspace and no team membership, plan type prolite.
I can confirm the diagnosis in the original report and add two things: the failure is fully reproducible, and there is a second, independent defect that turns the sign-out into what users perceive as a crash.
Environment
OpenAI.Codex 26.818.5229.0 (desktop client 26.818.41509, buildFlavor prod)
Electron / Chrome 151.0.7922.170, Node 24.14.0
Windows 10.0.19045 x64, Intel Core i7-3770K, 16 GB RAM
Account: personal, plan type prolite, subscription active until 2026-09-20, auth method chatgpt (email OTP)
For log correlation on your side:
installation id: 7e983c90-44e8-49a3-9901-7010e3875a0e
sentry session id: c8c1a1f0-d9b5-4097-8107-ec53f47485b7
sentry sid: 2138bd2254d942fc8e4971c97b21cafd
app session started 2026-08-22 19:53:59 UTC
failures at 2026-08-22 19:48:38 UTC and 20:02:27 UTC
Timestamps in the traces below are Europe/Berlin (UTC+2). Happy to share account-level identifiers privately.
Steps to reproduce
Sign in through the browser. Sign-in completes normally.
Use the app for a few minutes. Everything works: sidebar loads, task polling succeeds, pinned items appear.
Click a pinned project.
Within about three to five seconds the app drops to the signed-out state.
Reproduced twice in one session, with an identical request sequence both times.
Observed behaviour
The session is provably healthy right up to one specific request. wham/tasks/list polls once a minute and returned 200 on eight consecutive polls. Then, on opening the project:
22:02:23 200 /backend-api/settings/user
22:02:24 200 /backend-api/pins?item_type=conversation
22:02:24 200 /backend-api/pins?item_type=project
22:02:24 200 /backend-api/wham/usage
22:02:24 200 /backend-api/wham/accounts/check
22:02:24 200 /backend-api/gizmos/snorlax/sidebar
22:02:27 401 /backend-api/accounts/{account_id}/settings
22:02:28 401 /backend-api/accounts/{account_id}/settings (retry)
22:02:29 401 /backend-api/wham/onboarding/context
22:03:12 401 /backend-api/wham/tasks/list <-- returned 200 eight times before this
22:04:12 401 /backend-api/wham/tasks/list
Console output across the transition, showing the token being lost rather than expiring:
22:02:27 [electron-fetch-wrapper] desktop_fetch_auth_401
hadToken=true skipRetryReason=null tokenSource=cached willRetry=true
target="GET https://chatgpt.com/backend-api/accounts/:param/settings"
22:02:28 [AppServerConnection] app_server_connection.auth_status_result
authMethod=chatgpt cacheWrite=null hasToken=false
nullReason=auth_token_missing refreshToken=true tokenExpiryState=missing
22:02:29 [electron-message-handler] sa_server_request_failed
errorMessage="{\"detail\":\"Missing valid access token or actor biscuit\"}"
routePattern=/accounts/{account_id}/settings status=401
requestHeaderNames=["OAI-Language","X-OpenAI-Attach-Auth",
"X-OpenAI-Attach-Integrity-State","originator"]
rendererWindowVisible=true rendererWindowFocused=true
22:02:29 [electron-fetch-wrapper] desktop_fetch_auth_401
hadToken=false skipRetryReason=no_token_attached willRetry=false
target="GET https://chatgpt.com/backend-api/wham/:param/:param"
The state change is unambiguous: hadToken=true before the workspace-only call, hadToken=false on every call afterwards. A 401 from an endpoint that does not apply to this account type discards an otherwise valid session.
The first occurrence 14 minutes earlier followed the same path and additionally captured the app switching itself to the login flow:
21:48:34 ui.click (the project)
21:48:35 200 /backend-api/wham/accounts/check
21:48:38 401 /backend-api/accounts/{account_id}/settings
21:48:39 GET .../assets/login-route-*.js
21:48:39 GET .../assets/chatgpt-desktop-auth-url-*.js
21:48:39 GET .../assets/onboarding-entrypoint-*.js
21:48:39 GET .../assets/onboarding-login-content-*.js
21:48:39 electron renderer.destroyed url=https://chatgpt.com/?source=codex#pricing
21:48:39 401 /backend-api/wham/onboarding/context
Two distinct defects
Defect 1 - a workspace-only 401 invalidates a personal session. /backend-api/accounts/{account_id}/settings is not applicable to a personal account, so its 401 is expected. Treating it as an authentication failure, forcing a token refresh and tearing down the session is not.
Defect 2 - the resulting screen renders empty. Even granting the sign-out, the app should show a usable sign-in prompt. Instead the route renders nothing, with this console warning:
Matched leaf route at location "/" does not have an element or Component.
This means it will render an <Outlet /> with a null value by default resulting in an
"empty" page.
This is why the failure is widely reported as a crash. It is not one. During the whole episode all nine processes stay alive, the main window keeps responding (Responding = True), CPU usage stays near zero, and no crash dump is written to Crashpad\reports. Anyone triaging these reports as crashes will be looking in the wrong place.
Token state is not the problem
~/.codex/auth.json was intact before, during and after both failures, and was never rewritten (file mtime unchanged throughout):
auth_mode = chatgpt, OPENAI_API_KEY = null
access token valid for another 10 days (exp 2026-09-01), aud https://api.openai.com/v1
refresh token present
last_refresh predates both failures
So the client is discarding a valid session rather than reacting to an expired one.
Possibly related: plan type prolite
Three observations that may share a root cause in how prolite is handled:
/backend-api/payments/payment_methods returns 400: "Payment methods for mobile subscriptions must be managed in the mobile platform."
The last URL of the destroyed renderer is chatgpt.com/?source=codex#pricing, i.e. the app was routing toward a pricing or upsell page.
There are separate reports that the app-server provider probe rejects account.planType = "prolite" because the value is missing from its schema enum (accepted: free, go, plus, pro, team, business, enterprise, edu, unknown), leaving the model list empty.
It would be worth checking whether prolite is handled consistently across the account-settings, entitlement and provider-probe paths.
Side observation: same misleading "expired" framing in a second client
Possibly useful for triage, not part of this bug: a completely separate third-party client on the same machine talks to the same chatgpt.com/backend-api/codex endpoint with its own OAuth session (same account, same client_id, separate access and refresh tokens). It also surfaces 401s as "Provided authentication token is expired" while its token is likewise valid for another ten days.
Two independent clients therefore report token expiry for 401s that are not expiry. If the backend returns 401 for authorisation or plan-eligibility reasons rather than expiry, a more specific status or error body would let clients stop tearing down valid sessions.
Ruled out locally
Each of these was measured, not assumed:
App repair, app reset, and full uninstall plus reinstall
Complete reset of the Chromium profile at %APPDATA%\Codex\web\Codex (note: this lives outside the MSIX container, so the three Windows repair paths never touch it)
DPAPI decryption of os_crypt.encrypted_key - succeeds, yields a valid 32-byte AES key
codex:// protocol handler - resolves correctly to the app
Chrome's protocol_handler.excluded_schemes - empty, no silent block on the callback
Proxy and enterprise policies - none in effect
Hardware acceleration - disabling it changes nothing, and an HTTP 401 is not a rendering problem
Memory pressure - 7.4 GB free, all app processes together about 1.1 GB
Pending app updates - the update installed successfully; this build is current
Expected behaviour
Either skip the workspace-only account-settings request for personal accounts, or treat a 401 from it as non-fatal and keep the existing session. Additionally, the signed-out route should render an actual sign-in prompt rather than an empty page.
Confirmed workaround on Windows Stable, still reproducible on
OpenAI.Codex 26.818.5229.0.Observed failure pattern in the desktop logs matched this issue closely:
/backend-api/accounts/{account_id}/settings->401desktop_fetch_auth_401 hadToken=truehasToken=false,nullReason=auth_token_missing, whilerefreshToken=trueMissing valid access token or actor biscuit/account_info_token_unavailablecodex login statusin CLI still showedLogged in using ChatGPTWhat fixed Stable for me:
openai.com,auth.openai.com,chatgpt.com).Result: the sign-in loop stopped and Stable is working normally again. No reinstall,
Reset-AppxPackage,.codexdeletion, or downgrade was needed.This strongly supports the browser-side OpenAI/ChatGPT OAuth session/cookies workaround already reported in this thread, and confirms it also works on the 26.818 Stable branch.
Confirmed workaround that is currently working for me on Windows Desktop:
This is slightly different from only clearing cookies in the existing browser profile. In my case, isolating the login into a completely fresh browser profile/session is what made the Desktop authentication stable. It is working normally for me now.
Sharing in case anyone is blocked by the repeated sign-in / auto-logout loop.
Confirming on
OpenAI.Codex 26.818.8289.0(desktop client26.818.61809, bundled core0.149.0-alpha.4.3), Windows 11 Pro 10.0.26200, personal ChatGPT Pro account with no workspace and no team membership. Adding three things not yet in this thread: a strict per-launch correlation, a negative control that isolates the trigger, and a counter-forensics note about several log fields that are misleading people in this thread and elsewhere.1. Per-launch correlation across five consecutive launches: 5/5, no exceptions
Same machine, same build, five app launches within 100 minutes.
settings401countsGET /backend-api/accounts/{account_id}/settingsreturning 401;logoutis the UI returning to the signed-out state.| launch (local) | settings 401 | resumeStarted | resumeSuccess | logout |
|---|---|---|---|---|
| 18:17 | 0 | 2588 | 1 | no |
| 18:37 | 0 | 706 | 0 | no |
| 18:44 | 2 | 187 | 4 | yes |
| 18:58 | 2 | 11 | 11 | yes |
| 19:13 | 1 | 5 | 5 | yes |
The settings 401 is necessary and sufficient for the logout in every launch. The logout follows the 401 by 1–2 seconds each time:
hadToken=trueon the settings call, then every subsequent request logshadToken=false skipRetryReason=no_token_attached. The client discards a locally valid token —expwas 10 days out (2026-09-03), verified unexpired at the time of the logout.2. Negative control: the two clean launches were not healthy, they just never reached the call
This is worth stating because it rules out "opening an old thread" as the trigger. At 18:17 and 18:37 I had (for unrelated reasons) moved some session
.jsonlfiles off disk, so resume failed: 2588 resume attempts with 1 success, and 706 with 0. Those launches never issued the settings request at all and never logged out. Restoring the files made resume succeed, and the settings 401 plus logout returned immediately.So the ordering is: resume must complete before the client issues
getWorkspaceSettings(). A partially-broken thread store accidentally suppresses the bug. That matches @johnny-salz's code-level finding — the fallback fires once account data has settled tonullwith loading stopped.3. Counter-forensics:
cacheWrite,hasTokenandnullReasonare hardcoded literals, not measurementsSeveral reports here (and Codex's own self-diagnosis when I asked it) treat these fields as evidence about token state. In
app.asarfor this build they are constants in that single log branch:nullReasoncomes from a classifier that returnsauth_token_missingfor any chatgpt-mode account whose status response lacked a token — it is a label, not a diagnosis:Consequences for triage:
cacheWrite=nullnever indicates a failed cache write; it is emitted identically on every occurrence.hasToken=falsein this line does not mean the local token is gone. In my caseauth.jsonheld a valid unexpired token throughout.refresh_token_invalidatedappears 0 times in the 273 MBapp.asar, so where it shows up it originates from a server response body, not client logic. In my five launches there were 0 refresh events, yet the same logout occurred — so refresh-token invalidation is not required to reproduce this.actor biscuitis likewise absent from the bundle (0 occurrences);Missing valid access token or actor biscuitand{"detail":"Unauthorized"}are downstream consequences logged after the token is dropped, not the cause.last_refresh(present inauth.json) has 0 occurrences in the bundle — the desktop client never reads it; that field belongs to the Rust CLI.I also chased and refuted three plausible-looking local causes, in case they save someone else the time: a
poid=org-…claim on a personalplan_type=protoken is normal (personal accounts get a personal org id, andchatgpt_account_idmatchedtokens.account_idexactly); this account has no workspace switcher in its settings UI at all; and the"Payment methods for mobile subscriptions must be managed in the mobile platform."response also appears in the launches that did not log out, so it is unrelated background noise.Impact
codex login statusin the CLI continued to reportLogged in using ChatGPTthroughout, so the CLI and the desktop app disagree about auth state. The practical severity is that a failed subscription-info lookup — a non-critical read — invalidates an otherwise working authenticated session. Independent of the server-side 401, the client-side escalation from one 401 on a non-essential endpoint to discarding the token and signing out globally looks like the more tractable fix, and would make the endpoint problem invisible to users.Happy to provide the sanitized per-launch log extracts if that would help.
Following up on my report from 08/22 — the "sign out of all sessions server-side, then wait, then relaunch" workaround worked for me too.
Steps: chatgpt.com → Settings → Security → Active sessions → "Log out of all devices". Then waited about 30 minutes (the delay some others mentioned turned out to be real for me). Then relaunched the Desktop app (Windows, personal
proliteaccount, was on 26.818.8289.0) and signed in fresh.Since then the app has been working without any sign-out on opening pinned projects/threads. Adding this as another data point for anyone hitting the same 401-on-
accounts/settingsinvalidation.I can confirm that this issue is still reproducible on the latest Microsoft Store version available to me, using a personal ChatGPT Plus account. Advanced Account Security is disabled.
Environment:
Observed after a full logout and fresh sign-in:
Read-only comparison using the same freshly issued access token:
This indicates that the access token remains valid for Codex, but Desktop treats the workspace-only account-settings 401 as a global authentication failure. ChatGPT Web remains signed in and works normally. Resetting the app, clearing credentials/cache, and signing in again do not resolve it.
Confirming this on OpenAI.Codex 26.818.8289.0 for Windows. The same ChatGPT account is signed in on both a Mac and a Windows PC. Creating a new conversation on Windows works, but opening an existing conversation signs the Windows app out and requires authentication again. This started immediately after completing the new enhanced security verification. Please confirm whether simultaneous use on two computers is supported; if it is, please investigate the unexpected sign-out.
Additional Windows reproduction on 26.820.71523 (sanitized)
I am seeing the same repeated sign-in loop on Windows with Codex Desktop client 26.820.71523.
Context:
~/.codex/auth.jsonwas renamed/regenerated.CODEX_*orOPENAI_*environment variables are present.Sanitized log sequence:
The remote-control refresh path also reports:
and the auth recovery path reports that the access token cannot be refreshed because the refresh token was revoked.
The bundled Codex app-server/CLI still initializes successfully, so the failure appears isolated to the Desktop ChatGPT OAuth/session lifecycle rather than the repository, Git, or CLI runtime.
I have not included account IDs, tokens, thread IDs, email addresses, or raw logs. I will next test the browser-session workaround described in this issue (clear OpenAI/ChatGPT browser session and sign in with only the intended account) before attempting a Desktop rollback.
Additional Windows reproduction on newer builds:
thread ... already has an active writer; once Desktop is fully exited, that writer conflict can be removed. This appears separate from the authentication/logout failure.Expected behavior: opening/resuming an existing conversation should preserve the authenticated ChatGPT session instead of transitioning the Desktop runtime to signed-out state.
This looks consistent with the auth-state/refresh-token regression already described in this issue and related reports. Please prioritize a Desktop-side fix; the failure makes existing Codex conversations effectively unusable on affected Windows installations.
Confirmed workaround from another affected Windows user on 26.820.60940:
The root trigger in this case was multiple ChatGPT/OpenAI browser sessions/accounts being present during the Codex Desktop OAuth sign-in flow.
Observed behavior:
What fixed it:
chatgpt.comauth.openai.comopenai.comSign in with ChatGPTagain.Result: existing conversations now open normally and the automatic sign-out loop has stopped.
This strongly suggests that stale or multi-account browser OAuth state can cause Codex Desktop to obtain/use an inconsistent account/session context, which later collapses during thread resume/account refresh.
Recommendation for affected users: before reinstalling the app or deleting
~/.codex, first clear the browser-side OpenAI/ChatGPT OAuth session and retry with a single account. The local Codex sessions themselves do not need to be deleted.Confirmed on Windows with Codex Desktop 26.820.71523.
I hit the same auth loop after changing my ChatGPT password: sign-in succeeded, then the desktop app quickly returned to sign-in. Local troubleshooting did not resolve it (signed out active Codex sessions, regenerated
~/.codex/auth.json, tested without VPN, checked for CODEX/OPENAI env vars, used Windows Repair, then full App Reset). Logs showed the same sequence reported here:desktop_fetch_auth_401 hadToken=trueauth_token_missingtoken_revoked/ invalidated OAuth tokenhadToken=false skipRetryReason=no_token_attachedWhat finally fixed it was clearing the browser-side ChatGPT/OpenAI OAuth session, not more Codex app state:
chatgpt.com,openai.com, andauth.openai.com(or clear the browser session completely).Sign in with ChatGPTagain.After doing this, Codex remained signed in and completed new tasks normally. A stale pre-fix conversation later returned
thread not found, but opening a new thread worked correctly; this appeared to be leftover thread state from the earlier broken auth session, not an ongoing auth failure.This workaround may be worth surfacing in troubleshooting docs because local App Reset /
auth.jsonreset alone can leave the browser OAuth session unchanged and therefore reproduce the same revoked-token loop.Additional Windows reproduction on package 26.820.9563.0: the same workspace-settings 401 triggers forced authentication refresh, but the locally observed failure is a 30-second getAuthStatus timeout, not a confirmed refresh_token_invalidated response.
Environment
Two captured incidents
Times below are local UTC+08:00 on 2026-08-28 (equivalently 2026-08-27 UTC).
| Local time | Observation |
| --- | --- |
| 05:17:04 | Forced refresh starts after accounts/settings 401; no refresh-completion log before the later restart. |
| 05:17:34 | Failed to refresh authentication token. |
| 05:18:11 | Timed out waiting for MCP response to getAuthStatus; authenticatedAccountPresent=false, failureType=account_info_token_unavailable. |
| 05:35:21.841 | A second incident: accounts/settings 401 with hadToken=true, tokenSource=cached, willRetry=true. Backend records Refreshing token. |
| 05:35:51.874 | Failed to refresh authentication token, approximately 30 seconds later. |
| 05:36:25.310 | Timed out waiting for MCP response to getAuthStatus. |
| 05:36:25.337 | authenticatedAccountPresent=false; failureType=account_info_token_unavailable. |
| 05:36:46 | An active task is still writing an assistant progress message to its durable rollout. |
| 05:36:50.358 | Desktop logs stop_process; backend is restarted at approximately 05:36:53. |
Other settings requests immediately before the second incident repeatedly returned:
Must use workspace account for this operation.The user saw an apparent stall followed by the sign-in screen. This is not demonstrated to be an OS crash: during the authentication stall, thread/list and model/list requests still completed in approximately 0–3 ms. No matching Windows Application Error / WER / Application Hang or resource-exhaustion event was found in the inspected window. Approximately 21 GB of 31.84 GB RAM was free after restart; this is not a measurement of memory at the exact failure time.
Relevant client behavior
Read-only inspection of the installed desktop JavaScript found that the forced-refresh path calls getAuthStatus with a 30,000 ms local timeout. The fetchAuthToken catch path calls setAuthTokenCache(null) when the token generation is unchanged. The account-info lookup then reports no authenticated account after that request times out.
This identifies a client path from a transient refresh failure to an apparent logout. It does not establish why the OAuth refresh stalls, whether it is a network/server/internal synchronization issue, or that disk credentials were deleted.
Clearing the external Chrome login-site cookies, explicitly signing out, completing browser authorization again, and restarting did not prevent these later recurrences. We have not established which update introduced the behavior, and have not run a controlled alternate-network or standalone-CLI comparison on this machine.
Impact and requested investigation
Please distinguish a workspace-only settings rejection and a temporary authentication-refresh timeout from a confirmed invalid/revoked login, and investigate the backend refresh operation that stops completing while other RPCs remain responsive.
There is also an independently confirmed stale-history projection defect matching #41079. Returning to the sign-in screen / restarting exposes that stale projection, making later conversation turns appear lost. This is an interaction between two observed failures, not proof that they share one underlying cause.
Privacy: no tokens, account IDs, emails, thread IDs, project names, conversation content, raw logs, or databases are attached. This report was prepared from local read-only diagnostics with the affected user's authorization.