Auth: fetchAuthSession()/getCurrentUser() hang indefinitely after a cross-tab or abandoned OAuth (signInWithRedirect) flow
Before creating a new issue, please confirm:
- I have searched for duplicate or closed issues and couldn't find a duplicate matching my use-case and specifications.
Note: This is a follow-up to the closed issue #14344 ("Calling
getCurrentSessionpromise hangs after signing out in a different tab"). That issue was closed as a question, but the underlying library bug is real and reproducible on the latestaws-amplify. Opening this to track the fix.
Which UI component?
N/A (core aws-amplify/auth)
Gathering environment information is required for the timely resolution of issues.
[email protected] (also reported on 6.14.x)
Describe the bug
fetchAuthSession() (and getCurrentUser()) can hang forever — never resolving and never rejecting — after a cross-tab OAuth interaction.
signInWithRedirect() sets an inflightOAuth=true flag in localStorage, which is shared across all tabs of the origin. However, the mechanism that unblocks fetchAuthSession()/getCurrentUser() once OAuth completes (resolveAndClearInflightPromises) is an in-memory, per-tab array of resolvers that only runs in the tab that actually processes the OAuth redirect response — completeOAuthFlow on success, handleFailure on error.
As a result, any tab that only observes the shared flag but never runs the redirect callback blocks forever in TokenOrchestrator.waitForInflightOAuth():
- Cross-tab: Tab B calls
signInWithRedirect()and stays on the Cognito Hosted UI without finishing. Tab A then callsfetchAuthSession()→ reads the sharedinflightOAuth=true→ registers an in-memory promise its own runtime will never resolve → hangs. - Abandoned flow: any flow that sets
inflightOAuth=trueand is never completed leaves the flag inlocalStoragepermanently, so laterfetchAuthSession()calls hang.
Expected behavior
fetchAuthSession() should resolve (returning the current tokens, or null/no tokens) rather than hang indefinitely when another tab started or abandoned an OAuth flow. A tab that did not itself initiate the redirect should not be blocked by shared cross-tab OAuth state.
Reproduction steps
- Open the app in Tab A and Tab B (SPA using
aws-amplifyv6 + Cognito Hosted UI / Managed Login,response_type=code). - In Tab B, call
signInWithRedirect()and stay on the Hosted UI without completing sign-in (this writesinflightOAuth=trueto sharedlocalStorage). - In Tab A, call
fetchAuthSession(). - Observe that the promise in Tab A never resolves or rejects.
inflightOAuthremainstruein sharedlocalStorageandwaitForInflightOAuth()keeps waiting.
Reproduced deterministically with a minimal two-tab app; fetchAuthSession() in Tab A never settles.
Code Snippet
// Tab A
import { fetchAuthSession } from 'aws-amplify/auth';
window.onfocus = async () => {
console.log('will fetch session');
const session = await fetchAuthSession(); // never resolves/rejects
console.log('got session', session); // never reached
};Log output
will fetch session
(no further output — promise never settles)aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Desktop OS
macOS
Browser
Chrome, Safari
Additional information and screenshots
Root cause is the mismatch between the cross-tab shared inflightOAuth flag (localStorage) and the per-tab in-memory resolver array in packages/auth/src/providers/cognito/utils/oauth/inflightPromise.ts, consumed by TokenOrchestrator.waitForInflightOAuth().
Related: closed issue #14344.
A fix is proposed in PR #14940, which bounds the wait so a tab that did not initiate the flow can never hang (resolves when another tab clears the shared flag, with a bounded-timeout safety net for abandoned flows), without disturbing an OAuth flow genuinely in progress in another tab.
Source: aws-amplify/amplify-js