Skip to content

fix(codex): treat a bare WHAM 401 as transient while the main token is live - #1932

Closed
harryzhou2000 wants to merge 1 commit into
lidge-jun:devfrom
harryzhou2000:fix/wham-bare-401-transient
Closed

harryzhou2000 wants to merge 1 commit into
lidge-jun:devfrom
harryzhou2000:fix/wham-bare-401-transient

Conversation

@harryzhou2000

@harryzhou2000 harryzhou2000 commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

WHAM is the ChatGPT usage/quota endpoint (GET https://chatgpt.com/backend-api/wham/usage) that ocx polls for plan, rate-limit windows, and reset credits. A bare 401 from WHAM does not prove the local credential died: upstream edges can transiently reject a still-valid access token. ocx treated every 401 as terminal, so the GUI's periodic refresh flipped a healthy main account to needs-reauth within a minute.

This PR only marks the main account needsReauth when the response carries a terminal code (invalid_workspace_selected / invalid_refresh_token) or the local access-token JWT has actually expired. Bare 401s with a live token are transient and leave the account usable.

Tests: updated and added auth-api tests for live-token 401 (transient), expired-token 401 (terminal), and the BUG-R327 flow.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Aug 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/codex/auth-api.ts.

@github-actions

github-actions Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • hygiene: unsponsored_surface.

What to do

  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/codex/auth-api.ts.
  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.
@harryzhou2000 Tick the boxes once your local CI is green, your branch is on the latest dev commit, and every correct Codex and CodeRabbit finding is resolved.

@github-actions github-actions Bot added the bug Something isn't working label Aug 17, 2026
@coderabbitai

coderabbitai Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5fb9f9ef-50a9-4659-a03f-a2972ffb87ba

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@harryzhou2000
harryzhou2000 force-pushed the fix/wham-bare-401-transient branch from bb47f79 to c77aed5 Compare August 18, 2026 04:29
@harryzhou2000

harryzhou2000 commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor Author

@Wibias — when you get a chance, could you share your opinion on this one? It touches the auth surface (src/codex/auth-api.ts), so per MAINTAINERS.md it needs a maintainer to apply maintainer-sponsored after review. Happy to adjust the approach if you prefer something different.

@harryzhou2000
harryzhou2000 force-pushed the fix/wham-bare-401-transient branch from c77aed5 to fa77e5c Compare August 18, 2026 11:05
@harryzhou2000

Copy link
Copy Markdown
Contributor Author

@lidge-jun — could you share your opinion on this one when you have a moment? It changes the auth surface (src/codex/auth-api.ts): a bare WHAM 401 with a still-live access token is treated as transient instead of flipping the main account to needs-reauth. It is rebased onto the latest dev (fa77e5c) and tests are green locally; per MAINTAINERS.md it needs maintainer-sponsored after review. Happy to adjust if you prefer a different approach.

lidge-jun added a commit that referenced this pull request Aug 18, 2026
…ly live main token

Redesign of #1932. The idea — a bare 401 from WHAM should not flip the main
account to needsReauth while the local access token is still valid — is
correct, but its liveness gate (isMainAccountTokenLive) treats a JWT whose
exp cannot be decoded as live, so a genuinely dead credential would keep
every bare 401 'transient' and needsReauth could never flip.

This lands the transient-401 gate on a strict liveness check:
isMainAccountTokenVerifiablyLive() returns true only for a decodable,
still-future exp. An undecodable exp fails toward the terminal/reauth path.
Terminal body codes (invalid_refresh_token, invalid_workspace_selected)
remain terminal even when the token is live.

Credit: #1932 (transient bare-401 concept and test scaffolding).

Co-authored-by: PR #1932
lidge-jun added a commit that referenced this pull request Aug 18, 2026
fix(codex): treat a bare WHAM 401 as transient only for a verifiably live token (lands #1932)
@lidge-jun

Copy link
Copy Markdown
Owner

Landed via #2021 — your transient-401 gate with the reviewer-required tightening: liveness now requires a decodable future exp, so a dead credential cannot loop as transient. 186/0 + tsc. Thanks!

@lidge-jun lidge-jun closed this Aug 18, 2026
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
…ly live main token

Redesign of lidge-jun#1932. The idea — a bare 401 from WHAM should not flip the main
account to needsReauth while the local access token is still valid — is
correct, but its liveness gate (isMainAccountTokenLive) treats a JWT whose
exp cannot be decoded as live, so a genuinely dead credential would keep
every bare 401 'transient' and needsReauth could never flip.

This lands the transient-401 gate on a strict liveness check:
isMainAccountTokenVerifiablyLive() returns true only for a decodable,
still-future exp. An undecodable exp fails toward the terminal/reauth path.
Terminal body codes (invalid_refresh_token, invalid_workspace_selected)
remain terminal even when the token is live.

Credit: lidge-jun#1932 (transient bare-401 concept and test scaffolding).

Co-authored-by: PR lidge-jun#1932
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
fix(codex): treat a bare WHAM 401 as transient only for a verifiably live token (lands lidge-jun#1932)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants