Uh oh!
There was an error while loading. Please reload this page.
fix(codex): treat usage-limit stops as quota, not errors - #9236
Open
vitalyiegorov wants to merge 1 commit into
Open
fix(codex): treat usage-limit stops as quota, not errors#9236vitalyiegorov wants to merge 1 commit into
vitalyiegorov wants to merge 1 commit into
Conversation
Codex classifies plan limits, Business workspace credits, and spend caps alike as usageLimitExceeded. The adapter turned that into a runtime.error and a failed turn, so the thread went red with a generic error banner as if the provider had crashed. At the adapter boundary, a usage-limit stop now surfaces as a warning row carrying Codex's own sentence (reset time or workspace owner), and the turn it ends is cancelled rather than failed. Other errors are unchanged. Built with Claude Fable 5 in Claude Code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4 tasks
Contributor
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused Codex adapter bug fix that reclassifies provider-reported quota exhaustion using existing warning and cancelled-turn states. Tests cover the new mappings and preserve non-quota error behavior, while the documentation-only change has no runtime impact. You can add or adjust custom eligibility rules. Learn more. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
When Codex stops a turn because the account is out of quota, the thread now shows a warning row with Codex's own sentence and the turn ends quietly, instead of the thread going red with a generic runtime error banner.
Codex reports three different stops under one error code,
usageLimitExceeded: personal plan windows ("Your limit will reset at 6:00 PM"), Business/Enterprise workspace credits ("Your workspace is out of credits. Ask your workspace owner to refill…"), and workspace spend caps.CodexAdapternow recognizes that code in both places it arrives:errornotification becomes aruntime.warning(the labeled work-log row the clients already render) rather than aruntime.error, so the session is not marked errored;turn/completedthat follows is reported ascancelledrather thanfailed, with noerrorMessage, sosession.lastErrorstays empty and no red banner appears. The warning row already said why the turn ended.Every other Codex error keeps its existing path:
runtime.errorwithprovider_error, failed turn, red banner. Adapter-only — no contract, schema, migration, or client changes. A short FAQ indocs/user/providers-codex.mdexplains what the two kinds of message mean and what to do.Why
Fixes#9234. Out of quota is not a malfunction. Painting it as one makes users chase a crash that never happened, and for Business accounts (which stop on credits, not on a resetting window) the red banner is the only thing they see. Codex already tells us it is a limit; the adapter was throwing that classification away.
Handling it at the adapter boundary keeps orchestration untouched: ingestion already maps a non-failed turn to
ready/lastError: null, and the projection deriveslatestTurn.statefrom the session status, so the thread lands as a settled turn with the warning row as its last entry.cancelledis used rather thaninterruptedbecause clients label an interrupted latest turn "You stopped this response", which would be false here.This is the Codex half of the problem #7165 addresses for Claude; that PR will be trimmed to Claude only so each provider is one concern.
UI Changes
No new components: the after-state is the existing
runtime.warningrow in the work log. Both captures below come from the same local T3 server driving a fakecodex app-serverthat replays, byte for byte in the vendored schema, the sequence codex-rs emits for a Business workspace credit stop (errorwithcodexErrorInfo: "usageLimitExceeded",account/rateLimits/updatedwithworkspace_member_credits_depleted, thenturn/completedfailed). Only the branch differs.Before (main) — generic thread error banner, red "Runtime error" row, thread badged Failed in the sidebar:
After (this branch) — the same sentence as a warning row, no banner, no error state, composer ready:
For reference, the original report from a real Business account (#9234) shows the same red banner as the before state.
Related work
errornotifications are warnings; this PR extends the same boundary to quota stops.usageLimitExceededcode but for recovery and auto-resume; they do not change how a stop is presented. fix(codex): accept rate limit errors on thread resume #8897 / Codex rateLimitExceeded error makes threads permanently unresumable #8875 concern a different code (rateLimitExceeded) on thread resume.Checklist
Built with Claude Fable 5 in Claude Code.
🤖 Generated with Claude Code