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
V2 refresh deduplication ends before host credential persistence #90
V2 refresh deduplication ends before the OpenCode host persists the refreshed credential. A second concurrent connection resolve can therefore reuse the still-stored old refresh token and send it to the broker again.
In src/server/v2.ts, refreshes deduplicates by broker URL and refresh token, but .finally(() => refreshes.delete(key)) removes the entry as soon as the broker response completes. OpenCode @opencode/core@2.0.27 persists the returned credential after the plugin's refresh() promise resolves, leaving a gap between those events.
Evidence
An adversarial test in the final auth review gated host persistence, then started a second resolve after the first broker response. The second request replayed the old token and received 401; the first request succeeded and persisted the rotated token, so the next resolve recovered. The reproducer lived in scratch and is not committed.
This demonstrates a transient failing tool call when the broker rejects a replay. Supabase refresh-token single-use or token-family invalidation behavior remains unverified; this issue does not claim that replay invalidates the account.
Related: PR #87, reviewed at 008c8d7ff4b3a2e01cf2b1867913a9bb6598197e against OpenCode 2.0.27.
Expected behavior
Concurrent resolves using the same stale credential across the host persistence window should not issue duplicate broker refresh requests. Any mitigation must preserve per-account and per-Location isolation, clean up retained results safely, and propagate refresh failures to waiting callers.
Acceptance criteria
Add a deterministic test that gates host credential persistence after the first broker response, then starts a second resolve with the still-stored old token.
The second resolve does not issue a duplicate refresh request for that old token.
Both resolves converge on the persisted refreshed credential, or return a clear, retryable error if the host cannot safely share the result.
Failed refreshes release waiters and do not leave stale success entries.
Tests cover separate credentials and Locations to prevent cross-account result sharing.
Severity
Medium reliability issue. The reproduced impact is a transient tool failure during a narrow race; account reauthorization is not established.
Activity