v6.12.1
Two reported bugs, and the six follow-on defects found while making them hold.
Fixed
One ChatGPT login with two workspace subscriptions collapsed onto a single quota pool (#226). With one email or Apple ID on, say, Team and Plus, codex-limits reported the same plan and percentage for every entry, codex-switch kept draining the same pool, and logging in under the other workspace looked like it overwrote everything.
The login flow asks for every organization the account belongs to, and one entry was persisted per organization — but all of them shared that login's single OAuth token. The backend routes quota by ChatGPT account id and ignores organization ids, so those entries quietly fell back to the token's default subscription.
Each workspace subscription is its own ChatGPT account, so separate tokens are what give separate quotas. One login now persists exactly one account. Run opencode auth login once per workspace and the two subscriptions report independently.
A pool change that had already been saved could be reported as a fatal lock error (#224). Releasing the config lock could fail after the write landed — most often on Windows, where an antivirus scanner or the search indexer holding the lock directory open surfaces as EPERM/EBUSY. The change was on disk; the tool said it had failed.
A lock going stale mid-change killed the plugin process. The underlying lock library's default response to a compromised lock is to throw from inside a filesystem callback, which nothing here catches — so instead of one call failing, everything stopped. That is the "afterwards it completely stalls the sub tasks" half of the report.
Windows lock contention was not recognised as contention. Only one error code counted, and it is not the one Windows produces, so the retry guidance added for this case never fired there.
Parallel codex-pool calls each waited out the full retry budget in turn. Ten concurrent calls stalled for ten times the wait and then all failed anyway. Once one call establishes that another process holds the lock, the rest give up quickly instead of repeating the same wait.
The "config is locked" response broke callers harder than the error it replaced, dropping fields that every successful response carries. It now reports the pool as it stands on disk, in the usual shape, and names the condition with the same identifier used everywhere else.
Lock contention was classified as a configuration error — the category that means "go fix your settings" — when it is transient and resolves on its own.
The multi-worktree collision warning never actually throttled. It keyed on the other process's pid, so a peer that restarted looked new every time and the repeated warning it was meant to suppress kept coming.
Upgrading
No action required for the lock fixes.
For the workspace fix: existing accounts are not rewritten, because merging stored records risks discarding a single-use refresh token and permanently breaking an account. They now route correctly instead of being mis-billed, but duplicate rows written by earlier versions stay until you clear them. For a clean pool, run opencode auth login, choose the fresh (not add) login, then add the second workspace. See Troubleshooting.
Notes
If you relied on one account entry per organization, you will now see one entry per login instead. That is the fix — those extra entries never had their own quota.
Thanks to @AceRothstein71 for reporting #224 and opening the first fix, and to @JackTheCoconut for reporting #226 with a root cause already verified against the backend.
Full changelog: v6.12.0...v6.12.1