Skip to content

Conversation

@7ttp
Copy link
Contributor

@7ttp 7ttp commented Jan 10, 2026

Summary

Defers _notifyAllSubscribers call in _exchangeCodeForSession using setTimeout to prevent deadlock on iOS/Capacitor PKCE OAuth flow.

Problem

On iOS/Capacitor with PKCE flow, exchangeCodeForSession() would hang indefinitely when a subscriber callback (in onAuthStateChange) tried to call getSession() or make authenticated requests.

The deadlock occurred because:

  1. exchangeCodeForSession() acquires a lock via _acquireLock()
  2. Inside the lock, it calls await _notifyAllSubscribers() which awaits all subscriber callbacks
  3. If a subscriber callback calls getSession(), it tries to acquire the same lock
  4. The lock queues the getSession() call to wait for the current operation
  5. But the current operation is waiting for the subscriber callback to complete
  6. Deadlock: subscriber waits for getSession() which waits for lock which waits for subscriber

Solution

Defer _notifyAllSubscribers using setTimeout(..., 0) so it runs after the lock is released.
This matches the existing pattern used here: https://github.com/supabase/supabase-js/blob/master/packages/core/auth-js/src/GoTrueClient.ts#L521

Related

Closes #1566

Thanks @simplysparsh

@7ttp 7ttp requested review from a team as code owners January 10, 2026 14:32
@7ttp
Copy link
Contributor Author

7ttp commented Jan 11, 2026

@mandarini @grdsdev

@mandarini mandarini self-assigned this Jan 12, 2026
@mandarini mandarini merged commit 09aa106 into supabase:master Jan 12, 2026
25 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exchangeCodeForSession() doesn't update Authorization headers on iOS/mobile platforms

2 participants