[Bug] OAuth subscription exhaustion can leave the TUI on Waiting instead of surfacing the quota error #1405
Replies: 1 comment 1 reply
|
Independent corroboration from a third route, which I think narrows the cause usefully. I hit the same user-visible failure on a path that shares neither of your two variables: no OAuth, no TUI. Mine is a plain API-key What that eliminatesYour point 5 — the activity tracker holding A documented guarantee that did not holdThis is the part I find most actionable.
My case is that documented example, only more extreme: Control: the same invocation with Hypothesis, explicitly not verified: the cap is only consulted when a One requirement your "Expected behavior" list does not yet coverYour list is written for an interactive session: clear
I would suggest adding that to the user-visible rule, since it is the same fix with a different terminal surface, and it is the difference between a degraded run and a lost one. On your scoping questionNobody has answered it, so for whatever an outside data point is worth: one focused issue for the user-visible rule reads better than provider-specific splits, precisely because the rule is provider-independent — three different provider paths, one symptom. The provider-specific work (nested Codex quota parsing, Anthropic OAuth metadata) is then implementation detail under it, and the stream-bound fix is the one that likely covers routes nobody has reported yet, including mine. Happy to re-run any proposed fix against the |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Affected area: provider error handling, automatic retry, and the interactive TUI.
When an OAuth-backed model subscription reaches its usage limit, Prime Agent can stay on
Waitingwithout displaying the provider's quota error. In my reproductions, the request ended only after I aborted it. The durable session entry then containedRequest was aborted, zero usage, and no indication that the account was out of quota.I observed this with Anthropic OAuth in two independent Prime Agent sessions at the same time. I also replayed the Codex
usage_limit_reachedresponse against the installed 0.7.2 provider. That deterministic replay found another route to the same visible failure: Codex retries a terminal quota response and reads the nested stream error incorrectly.The Anthropic stall and the explicit Codex error may require separate changes. The user-visible rule can be the same: a terminal subscription limit should end the request, display any reset information supplied by the provider, and clear
Waiting.Local Anthropic evidence
I recorded the following on:
6.17.0-1018-nvidia)/loginsettings.jsonwith noretry.provideror transport overrideThe timestamps below come from two local JSONL session journals. I intentionally omitted prompt text, tool output, paths, account data, request IDs, and full session IDs.
aborted,Request was aborted, 0 tokensaborted,Request was aborted, 0 tokensaborted,Request was aborted, 0 tokensaborted,Request was aborted, 0 tokensThe first two rows ended within 30 seconds of each other. The second pair of rows were model continuations in two concurrent sessions using the same Anthropic OAuth subscription. I confirmed from the provider account state that the Anthropic subscription was exhausted at the time. Prime Agent's journals did not record a provider quota code.
Prime Agent did not persist a provider quota event or error in these journals. This sanitized assistant entry is the only terminal evidence:
{ "role": "assistant", "provider": "anthropic", "usage": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0, "totalTokens": 0 }, "stopReason": "aborted", "errorMessage": "Request was aborted" }The full session files contain private prompts and tool output, so I am not attaching them publicly. I can provide a narrower sanitized trace if a maintainer specifies which event fields would help.
Deterministic Codex replay
For a separate test, I replaced the installed provider transport with local mocks and sent the nested quota payload captured in #863:
Against the installed 0.7.2 code, the HTTP 429 path made four provider calls and spent about 7 seconds in internal backoff before returning
You have hit your ChatGPT usage limit (pro plan). Try again in ~10 min.The WebSocket error event instead emittedCodex error: {"type":"error",...}, exposing the raw payload. The friendly quota message was absent.This replay used no credentials or provider traffic, and it made no paid request. It confirms that the provider retries an explicit terminal quota response; after the error is emitted,
AgentSession._isRetryableErroralso classifies it as retryable.Reproduction
/login.Waitingwithout a quota message.Request was aborted, without the provider limit or reset information.The Codex path is the deterministic local-mock replay above. It covers the explicit-error variant without exhausting a real subscription.
Relevant code on current
mainI checked current
mainat97b994c3:MAX_RETRIES = 3instead of using the configured provider retry budget.mapCodexEventsreadsevent.codeandevent.message. The real quota response puts those values underevent.error.typeandevent.error.message, so this path falls back toJSON.stringify(event).openai-codex-responses.tsandanthropic.ts. If the provider leaves the connection open without model data, no error reaches the session.AgentSession._isRetryableErrorstill retries errors by default unless they match one of a few exclusions. It has no exclusion for terminal quota errors.waitingand keeps that state until model output arrives. In the TUI, a silent quota response or stalled stream therefore looks the same as healthy time-to-first-token.Expected behavior
AgentSessionlayers.Waitingand display a transport or stall error.Prior reports and implementation attempts
This consolidates existing reports under the new discussion-first process; it is not a new discovery.
Prime Agent items #863, #871, #1232, #1362, and #1180 were closed during the issue/PR queue cleanup and migration to Discussions, not because the current source paths were fixed. #795 is open.
Would maintainers prefer one focused issue for the user-visible rule, with separate implementation PRs for quota parsing and classification versus the stream timeout? Or should this first be split into provider-specific discussions? If invited, I can implement the requested scope with faux/mock-provider regressions.
All reactions