Repository navigation
fix: Codex account switch releases the conversation, Reset usage on the limit banner - #82
Merged
Merged
Conversation
Detach only unloaded native threads still bound to the old session, but an account switch rebinds the thread to the new account's session in the same commit (and removes the old session's projection binding), so the root conversation was never unsubscribed and the old account's app-server held its writer lock indefinitely. The new account's resume then failed with 'This conversation is open in another Codex client'. Detach now also unloads this thread's same-driver native threads that were rebound away, taking the driver from the live runtime. Codex also keeps the lock ~60s after unsubscribe until its idle sweep closes the thread, so a resume refused for a thread this server released waits up to 90s for thread/closed and retries once; threads held by genuinely external clients still fail immediately. Model: muse-wonder-1.0-contributor (Muse Code)
The usage panel could spend a banked reset credit, but the usage-limit recovery banner/card only offered Resume at reset and Snooze until reset. When the limited account reports banked reset credits, the banner (web/desktop) and card (iOS/Android) now offer Reset usage, which confirms then redeems a credit via the existing consumeResetCredit command. Mobile's redemption hook moves to usage/useResetCredit.ts so the panel and card share it. Model: muse-wonder-1.0-contributor (Muse Code)
|
Guard redemption before awaiting the RPC so confirmations already opened cannot submit overlapping reset requests. Release the guard on success, typed command failure or rejected transport, preserving execution-time permission checks and explicit user confirmation. Add focused hook regressions for duplicate approvals, each completion path, subsequent attempts and permission revocation. The exact hook source passed isolated controlled-promise checks with framework/transport stubs; the full React/vite-plus suite and changed-file gate remain hosted validation.
Apply the mobile single-flight guard to the web/desktop usage hook while preserving its reset/message result for the recovery banner. Clear pending state after success, typed failure or transport rejection and recheck the current management permission on each attempt. Add a managed browser hook test for overlapping submissions, all completion paths and retry after permission changes. Hash-verified source extraction reproduced duplicate requests before and passed controlled-promise checks after; framework and RPC boundaries were stubbed. TypeScript syntax and whitespace checks passed. Actual React/browser execution, check:changed and full CI remain required; repository dependencies are unavailable locally.
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 free
to 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.
Two phone-reported bugs, plus the root cause of why quitting the app was the only workaround.
1. Switching Codex accounts stranded the conversation
Hitting the usage limit on one Codex account, switching the thread to another Codex account, and sending failed with "This conversation is open in another Codex client" — forever, until the desktop app was quit.
Root causes, from the server logs and traces of the failed thread:
ProviderSessionManager.detachonly unloaded native threads still bound to the old session in the projection. An account switch rebinds the thread to the new account's session in the same commit, so the main conversation was never unsubscribed on the old account's app-server (only a subagent's was), and that process held Codex's writer lock indefinitely. Quitting the app killed the process, which is why quit-and-reopen "worked".thread/unsubscribe, Codex holds the lock until its idle sweep emitsthread/closedabout 60s later, while turn-start retries span ~1.5s.Fix: detach also unloads this thread's same-driver native threads that were rebound to another session, taking the driver from the live runtime (the detached event has already removed the session's projection binding, so the projection cannot supply it). A process-wide release registry records threads this server unsubscribed; a resume refused for one of those waits up to 90s for
thread/closed(or app-server exit) and retries once. Threads held by genuinely external clients (Codex app/CLI/IDE) still fail immediately with the same message. Expect the first message after a switch to pause up to ~a minute instead of erroring.2. No way to reset usage from the limit banner
The usage-limit banner/card only offered "Resume at reset" and "Snooze until reset", though the usage panel could already spend a banked reset credit. When the limited account reports banked reset credits, the banner (web/desktop) and card (iOS/Android) now offer Reset usage: confirm, redeem via the existing
consumeResetCreditcommand, then send to continue. It appears even when no reset time is known and respects the providers-manage scope. Mobile's redemption hook moves tousage/useResetCredit.tsso panel and card share it.Proof
vp run check:changedpasses: format, lint, knip, typecheck (41 packages), tests beside the changes, React compiler. Server suites: 289 passed.Model: muse-wonder-1.0-contributor (Muse Code)