Desktop 26.623.42026: 'Oops, an error has occurred' takes over full home screen when boot-time metadata calls fail (HTTP 429 or offline)
Summary
When boot-time backend metadata calls fail — either because the ChatGPT plan has hit its daily Codex usage limit (HTTP 429 usage_limit_reached) or because the machine is offline (net::ERR_INTERNET_DISCONNECTED) — the desktop renderer's error boundary takes over the entire home screen: sidebar gone, chat history gone, no graceful degradation. The user sees only "Oops, an error has occurred" with Update Codex / Try again buttons. Clicking Try again re-throws the same error and the home screen never recovers until the underlying backend issue is resolved.
Even after the quota window resets (or network is restored), the app should never lose its entire home screen due to a backend metadata fetch failing.
Steps to reproduce
Either of the following deterministically reproduces it:
- Quota path: Burn through the daily Codex usage limit on a ChatGPT Pro-lite plan so
GET https://chatgpt.com/backend-api/wham/usage(and friends) return HTTP429 usage_limit_reached. Launch / relaunch Codex Desktop. - Offline path: Disable network (Wi-Fi off / airplane mode) so
electron.netrequests fail withnet::ERR_INTERNET_DISCONNECTED. Launch / relaunch Codex Desktop.
In either case the renderer immediately flips to the error boundary on the full home screen.
Expected behavior
The home screen should render with:
- Sidebar, chat list, and recent threads visible (use cached data if available, empty state if not).
- An empty or skeleton PR list / automations list.
- A small non-blocking error indicator (toast / inline banner) explaining that backend metadata couldn't be loaded.
A failed wham/usage or wham/tasks/list or codex/remote/control/environments call must not be allowed to unmount the entire home shell.
Actual behavior
Full home screen replaced by the error boundary:
Oops, an error has occurred Update Codex Try again
No sidebar. No chat list. No way to navigate. Clicking Try again remounts and immediately re-throws.
Stack traces (captured live via Chrome DevTools Protocol — Runtime.exceptionThrown + Runtime.consoleAPICalled.error)
Uncaught AggregateError
at Nn (app://-/assets/app-initial~app-main~worktree-init-v2-page~remote-conversation-page~new-thread-panel-page~o~dv5z3ftk-BhBbJNnt.js:1:42159)
at r (.../app-initial~app-main~worktree-init-v2-page~remote-conversation-page~new-thread-panel-page~o~dv5z3ftk-BhBbJNnt.js:1:45006)
at .../app-initial~app-main~worktree-init-v2-page~remote-conversation-page~new-thread-panel-page~o~dv5z3ftk-BhBbJNnt.js:1:4970
at Array.forEach
TypeError: Cannot read properties of undefined (reading 'trim')
at app://-/assets/app-initial~app-main~worktree-init-v2-page~remote-conversation-page~pull-requests-page~plug~kmtatxxf-DEE2TwPG.js:545:144825
at Array.map
at yK (.../pull-requests-page~plug~kmtatxxf-DEE2TwPG.js:545:144766)
Companion error:
TypeError: Cannot read properties of undefined (reading 'projectId')
Sentry / electron breadcrumbs preceding the crash
[global-state] Failed to persist global state errorCode=EPERM (only when chflags uchg was set; resolved separately)
[remote-connections/window-context] refresh_remote_control_for_local_identity_failed errorMessage=net::ERR_INTERNET_DISCONNECTED
electron.net: GET https://chatgpt.com/backend-api/codex/remote/control/environments?limit=100
electron.net: GET https://chatgpt.com/backend-api/wham/tasks/list?limit=20&task_filter=current
electron.net: GET https://chatgpt.com/backend-api/wham/usage
[sparkle] Update aborted with error: SUSparkleErrorDomain Code=2001
[electron-message-handler] [desktop-notifications][global-error] AggregateError
[electron-message-handler] error boundary componentStack="\n at zQ (app://-/assets/app-initial~app-main~automations-page-BfqUlSo6.js:47:339842)\n at ke (...)"
Diagnosis hint
The pull-requests-page bundle's yK is calling .trim() inside an Array.map over a list whose items are expected to have a string field — but when the backend returns 429 / network error, that list is undefined or its items are missing the field. The crash bubbles up through the automations-page error boundary, which appears to be too high in the tree (wrapping the home shell instead of just the PR/automations panel).
Two fixes would prevent the full-screen takeover:
- Guard the
.trim()/.projectIdaccesses against undefined items insideyK(pull-requests-pagebundle). - Catch fetch failures from
wham/usage,wham/tasks/list, andcodex/remote/control/environmentsin their TanStack-Query callers and resolve to empty arrays so the page can render an empty state instead of throwing through the boundary. - Move the error boundary below the home shell so a single panel's crash doesn't unmount the sidebar / chat list.
Environment
- Codex.app version 26.623.42026
- macOS 26.5.1 (Apple Silicon / arm64)
- Bundled CLI: 0.142.2
- Auth + token: healthy (
codex doctor17/17 ok) - CLI works fine — this is renderer-side only.