Skip to content

fix(NOISSUE-0000): Infinite refresh loop when session has RefreshTokenError#2796

Merged
MrLeonix merged 3 commits intomainfrom
fix/infinite-auth-loops
Mar 2, 2026
Merged

fix(NOISSUE-0000): Infinite refresh loop when session has RefreshTokenError#2796
MrLeonix merged 3 commits intomainfrom
fix/infinite-auth-loops

Conversation

@MrLeonix
Copy link
Contributor

@MrLeonix MrLeonix commented Feb 27, 2026

Problem

Users with an expired or revoked refresh token were stuck in an infinite loop on the home page, with the console repeatedly logging:

[auth-next-client] Session has error: RefreshTokenError

The proactive token refresh effect in useImmutableSession was responsible:

  useEffect(() => {
    if (!session?.accessTokenExpires) return;
    // No check for session.error ← bug
    if (timeUntilExpiry <= 0) {
      deduplicatedUpdate(() => updateRef.current()); // fires even on known-broken sessions
    }
  }, [session?.accessTokenExpires]); // session.error not tracked ← bug

When a refresh fails, the server sets session.error = 'RefreshTokenError' and rewrites the JWT — which updates session.accessTokenExpires as a side effect of signing the token. That new value triggered the effect again, which called update() again, which failed again, repeating indefinitely.

Each retry cycle caused isAuthenticated to briefly flicker during the loading phase, which caused WalletProvider to re-invoke connectWallet → which called getUser() → which logged the warning.

Fix

Added an early-return guard and tracked session?.error in the dependency array:

  useEffect(() => {
    if (!session?.accessTokenExpires) return;
    if (session?.error) return; // Don't retry a known-failing refresh

    if (timeUntilExpiry <= 0) {
      deduplicatedUpdate(() => updateRef.current());
    }
  }, [session?.accessTokenExpires, session?.error]);

Adding session?.error to the dep array also ensures that if the error later clears (e.g. user re-authenticates in the same session lifecycle), the effect re-evaluates and background refreshes resume correctly.

Impact

The ability to auto-refresh based on access token expiration is lost, since we'll simply interrupt the flow when there is an error AND access token is expired - we get in a loop. I'm looking into ways to overcome this.

@MrLeonix MrLeonix requested a review from a team as a code owner February 27, 2026 05:28
@nx-cloud
Copy link

nx-cloud bot commented Feb 27, 2026

View your CI Pipeline Execution ↗ for commit daad55e

Command Status Duration Result
nx affected -t build,lint,test ✅ Succeeded 1m 9s View ↗
nx run-many -p @imtbl/sdk,@imtbl/checkout-widge... ✅ Succeeded 4s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-27 05:42:38 UTC

@MrLeonix MrLeonix changed the title Fix: Infinite refresh loop when session has RefreshTokenError fix(NOISSUE-0000): Infinite refresh loop when session has RefreshTokenError Feb 27, 2026
@MrLeonix MrLeonix added this pull request to the merge queue Mar 1, 2026
Merged via the queue into main with commit 8ff9833 Mar 2, 2026
10 of 11 checks passed
@MrLeonix MrLeonix deleted the fix/infinite-auth-loops branch March 2, 2026 00:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants