Skip to content

Commit eb69205

Browse files
committed
fix(mcp): drop a server's prior in-flight OAuth flow when it is retried
Each start mints a new `state`, so an abandoned attempt's safety timeout was keyed under a different state than its retry and never cleared. In the contrived case where both stayed pending ~10 min, the stale timer would clear the newer flow's spinner. Sweep any prior in-flight flow for the same serverId on a new start (replacing the can't-happen same-state check). Result delivery was already correct; this makes the state machine airtight.
1 parent 3553676 commit eb69205

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

apps/sim/hooks/mcp/use-mcp-oauth-popup.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,17 @@ export function useMcpOauthPopup({ workspaceId }: UseMcpOauthPopupProps) {
141141
return
142142
}
143143
const { popup, state } = result
144+
// Drop any prior in-flight flow for this server (e.g. an abandoned attempt now being
145+
// retried) so its stale safety timeout can't later clear this new flow's state.
146+
for (const [prevState, flow] of pendingFlowsRef.current) {
147+
if (flow.serverId === serverId) {
148+
window.clearTimeout(flow.timeout)
149+
pendingFlowsRef.current.delete(prevState)
150+
}
151+
}
144152
// Track this in-flight flow keyed by its `state` nonce for the BroadcastChannel gate,
145153
// bounded by a safety timeout in case no result ever arrives (popup abandoned, or a
146154
// callback failure the client can't otherwise clear).
147-
const existing = pendingFlowsRef.current.get(state)
148-
if (existing !== undefined) window.clearTimeout(existing.timeout)
149155
pendingFlowsRef.current.set(state, {
150156
serverId,
151157
timeout: window.setTimeout(() => settleFlow(state), OAUTH_FLOW_TIMEOUT_MS),

0 commit comments

Comments
 (0)