Bug report
Describe the bug
I encountered a situation where Supabase Auth never finish initializing.
-
The impact on my app is that it never finishes initializing and any auth operation hangs.
-
I already checked that onAuthStateChange is not async and doesn't call any Supabase API, so #762 doesn't apply.
-
The GoTrueClient initialization hangs indefinitely on some devices (in my case, Chrome Android) due to a lack of timeouts in the Web Locks API implementation.
-
I investigated this by digging into the source code and enabling the undocumented debug option. On the affected device, the #_acquireLock call never resolved
| On a working device, the debug log is normal |
On a problematic device, it got stuck at #_acquireLock |
 |
 |
Additionally, on a problematic device, checking supabase.auth.initializePromise returns a never-resolving promise.
-
It seems that a previous lock wasn't properly released… when I run await navigator.locks.query() I see that some locks are being held indefinitely.
| Held locks |
 |
-
Is it really a good idea to wait for a lock indefinitely?? Sorry if I sound frustrated, but I kinda am – I just paid for Supabase Pro and didn't expect this from a professional auth solution. I kinda spent an hour scratching my head figuring out what's wrong with my app. That said, I really appreciate the overall quality of Supabase and believe this is just an edge case to be fixed. I hope this investgation will be useful.
To Reproduce
This issue is not easily reproducible as it appears to be race condition or environment-dependent. However, it occurs in production on real devices where users experience complete authentication failure.
The fundamental issue is that the current implementation holds Web Locks indefinitely without a timeout, which violates basic concurrency principles. Any scenario that prevents proper lock cleanup can trigger this deadlock.
Expected behavior
Supabase Auth should be able to recover from a situation where the lock is not properly released. The lock mechanism should have a timeout and fallback to ensure the client doesn't hang indefinitely.
Currently, the there is no acquireTimeout (-1 means no timeout):
https://github.com/supabase/auth-js/blob/aadf02e63179746a06451f4247a370dfd05740ea/src/GoTrueClient.ts#L358-L362
Maybe it should be set to some sane value, like maybe 1 minute.
Screenshots
| The app doesn't launch as Auth never finished initializing, and User sees a white page. |
 |
System information
- OS: Android
- Browser: Chrome
- Version of supabase-js: 2.71.1
- Affected code:
@supabase/auth-js GoTrueClient
Additional context
Current workaround
Until a proper lease is implemented, I am currently working around this issue by specifying a noOpLock when initializing Supabase. However I don’t know what might go wrong if we skip the locks.
const noOpLock = async (name: string, acquireTimeout: number, fn: () => Promise<any>) => {
return await fn()
}
const supabase = createClient(url, key, {
auth: { lock: noOpLock }
})
Debug session and debug log
Checking the locks in JS Console
await navigator.locks.query()
{
held: [
{clientId: '0ccb43ce-27c2-423e-8cbe-63a9c2da37b4', mode: 'exclusive', name: 'lock:sb-nmzhiwafofgwvqucnbds-auth-token'}
],
pending: [
{clientId: '0ccb43ce-27c2-423e-8cbe-63a9c2da37b4', mode: 'exclusive', name: 'lock:sb-nmzhiwafofgwvqucnbds-auth-token'},
{clientId: 'e6ee664e-e2d9-4f1d-8a9a-0ab0b5e83ee6', mode: 'exclusive', name: 'lock:sb-nmzhiwafofgwvqucnbds-auth-token'},
{clientId: 'e6ee664e-e2d9-4f1d-8a9a-0ab0b5e83ee6', mode: 'exclusive', name: 'lock:sb-nmzhiwafofgwvqucnbds-auth-token'},
{clientId: '9d09c2ce-ac43-4783-b356-e988cae6bc26', mode: 'exclusive', name: 'lock:sb-nmzhiwafofgwvqucnbds-auth-token'}
]
}
Debug logs showing the hang:
GoTrueClient@0 (2.71.1) 2025-09-13T19:24:55.355Z #_acquireLock begin -1
GoTrueClient@0 (2.71.1) 2025-09-13T19:24:55.355Z #onAuthStateChange() registered callback with id a5571c4b-9f69-4111-b314-119f2e0ecb87
(hangs here - never proceeds to lock acquisition)
Bug report
Describe the bug
I encountered a situation where Supabase Auth never finish initializing.
The impact on my app is that it never finishes initializing and any auth operation hangs.
I already checked that
onAuthStateChangeis not async and doesn't call any Supabase API, so #762 doesn't apply.The
GoTrueClientinitialization hangs indefinitely on some devices (in my case, Chrome Android) due to a lack of timeouts in the Web Locks API implementation.I investigated this by digging into the source code and enabling the undocumented
debugoption. On the affected device, the#_acquireLockcall never resolved#_acquireLockAdditionally, on a problematic device, checking
supabase.auth.initializePromisereturns a never-resolving promise.It seems that a previous lock wasn't properly released… when I run
await navigator.locks.query()I see that some locks are being held indefinitely.Is it really a good idea to wait for a lock indefinitely?? Sorry if I sound frustrated, but I kinda am – I just paid for Supabase Pro and didn't expect this from a professional auth solution. I kinda spent an hour scratching my head figuring out what's wrong with my app. That said, I really appreciate the overall quality of Supabase and believe this is just an edge case to be fixed. I hope this investgation will be useful.
To Reproduce
This issue is not easily reproducible as it appears to be race condition or environment-dependent. However, it occurs in production on real devices where users experience complete authentication failure.
The fundamental issue is that the current implementation holds Web Locks indefinitely without a timeout, which violates basic concurrency principles. Any scenario that prevents proper lock cleanup can trigger this deadlock.
Expected behavior
Supabase Auth should be able to recover from a situation where the lock is not properly released. The lock mechanism should have a timeout and fallback to ensure the client doesn't hang indefinitely.
Currently, the there is no
acquireTimeout(-1 means no timeout):https://github.com/supabase/auth-js/blob/aadf02e63179746a06451f4247a370dfd05740ea/src/GoTrueClient.ts#L358-L362
Maybe it should be set to some sane value, like maybe 1 minute.
Screenshots
System information
@supabase/auth-jsGoTrueClientAdditional context
Current workaround
Until a proper lease is implemented, I am currently working around this issue by specifying a
noOpLockwhen initializing Supabase. However I don’t know what might go wrong if we skip the locks.Debug session and debug log
Checking the locks in JS Console
Debug logs showing the hang: