You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: OAuth token responses with invalid expires_in produce NaN expiries that never refresh #1417
OAuth token responses are parsed into credential expiries in four places without a Number.isFinite guard on expires_in. A malformed upstream response (missing, NaN, or string expires_in) yields a NaNexpiry that flows into downstream time comparisons, where NaN <= x is always false — the credential is treated as never-expiring and never refreshed. This is the same data-quality class as the recently merged #1366/#1369 fix (Number.isFinite guards on local token expiry parsing) that remains unfixed at the token-response parse sites.
src/oauth/kimi.ts:163 — Date.now() + payload.expires_in * 1000 - OAUTH_EXPIRY_SKEW_MS — line 154 checks typeof !== "number", but NaN passes (typeof NaN === "number")
src/oauth/chatgpt.ts:55 — Date.now() + ((data.expires_in as number) ?? 3600) * 1000 — ?? only guards null/undefined; NaN or a numeric string passes through
src/codex/account-store.ts:498 — Date.now() + data.expires_in * 1000 — no validation at all
Reference implementation with the correct guard already exists at src/oauth/xai.ts:128-129:
Observe the stored credential carries expires: NaN, so expires <= now is always false — the credential never refreshes and ocx status reports it as logged in indefinitely (its health/refresh machinery cannot detect expiry).
Expected: a non-finite expires_in falls back to the same default used for a missing field (e.g. 3600s) so the credential stays refreshable.
Opened a fix: #1418 (base dev, maintainer edits enabled).
All four sites now use the typeof === "number" && Number.isFinite(...) pattern already established at src/oauth/xai.ts:128-129, falling back to a 3600s default (or rejecting, for Kimi's required-field semantics). No getLoginStatus / expiry-comparison changes — parse/adoption time only, per the lazy-refresh contract from #1369.
Tests: 5 new (account-store 1, kimi 1, anthropic 1, chatgpt 2); targeted 47/47, OAuth+anthropic+account-store suite 406/406, tsc --noEmit clean.
Verified against PR #1418 exact head 355b69e5b003edebe3f543d1818a9618fa075b14. The negative-duration and computed-overflow gaps are fixed across all four adoption paths, the fallback windows are pinned by tests, and the failed macOS job passed on rerun. I approved the authentication-boundary change after the exact-head security and CI review.
The PR is still draft because the author has not yet ticked the now-proven final checklist item, and an additional maintainer review is still requested. Leaving this issue open until the fix is actually integrated; PR-to-dev alone would not auto-close an issue whose default branch is main.
Status correction: PR #1418 is now ready for review at the same approved exact head 355b69e5b003edebe3f543d1818a9618fa075b14. The author completed the readiness checklist, the PR carries maintainer-sponsored and review-ready, and the authentication-boundary approval remains current.
lidge-jun and Wibias are still requested for independent review. Keeping this issue open until the PR is actually integrated; no direct merge is being performed here.
Activity
Bruce-Yii commentedon Aug 10, 2026
Opened a fix: #1418 (base
dev, maintainer edits enabled).All four sites now use the
typeof === "number" && Number.isFinite(...)pattern already established atsrc/oauth/xai.ts:128-129, falling back to a 3600s default (or rejecting, for Kimi's required-field semantics). NogetLoginStatus/ expiry-comparison changes — parse/adoption time only, per the lazy-refresh contract from #1369.Tests: 5 new (account-store 1, kimi 1, anthropic 1, chatgpt 2); targeted 47/47, OAuth+anthropic+account-store suite 406/406,
tsc --noEmitclean.Ingwannu commentedon Aug 10, 2026
Verified against PR #1418 exact head
355b69e5b003edebe3f543d1818a9618fa075b14. The negative-duration and computed-overflow gaps are fixed across all four adoption paths, the fallback windows are pinned by tests, and the failed macOS job passed on rerun. I approved the authentication-boundary change after the exact-head security and CI review.The PR is still draft because the author has not yet ticked the now-proven final checklist item, and an additional maintainer review is still requested. Leaving this issue open until the fix is actually integrated; PR-to-
devalone would not auto-close an issue whose default branch ismain.Ingwannu commentedon Aug 10, 2026
Status correction: PR #1418 is now ready for review at the same approved exact head
355b69e5b003edebe3f543d1818a9618fa075b14. The author completed the readiness checklist, the PR carriesmaintainer-sponsoredandreview-ready, and the authentication-boundary approval remains current.lidge-junandWibiasare still requested for independent review. Keeping this issue open until the PR is actually integrated; no direct merge is being performed here.