Skip to content

Conversation

@yogeshchoudhary147
Copy link
Contributor

@yogeshchoudhary147 yogeshchoudhary147 commented Jan 13, 2026

Problem

Customers experiencing "Invalid state" errors after upgrading to v2.8.0 when calling getTokenSilently() for multiple audiences in parallel with iframe-based authentication.

Root Cause: PR #1408 changed locking from global to per-audience to enable MRRT parallelization. This allows concurrent iframes to overwrite each other's state parameter in Auth0's server-side session.

Reproduces: v2.8.0+ ✅ | v2.7.0 ❌

Demo Video

Here's a video demonstrating the bug and the fix:

Screen.Recording.2026-01-15.at.7.51.12.PM.mov

What the video shows:

  • Without the fix (v2.8.0): "Invalid state" errors when making parallel iframe calls
  • With the fix: Both parallel iframe calls succeed with two-tier locking

Solution

Implement two-tier locking:

  • Outer lock (per-audience): Prevents duplicate calls for same audience → preserves MRRT performance
  • Inner lock (global iframe): Serializes iframe authorization flows → prevents session state conflicts

Refresh token flows bypass the inner lock and remain fully parallel.

Changes

  • Added buildIframeLockKey() to create global iframe lock key
  • Modified _getTokenFromIFrame() to acquire/release lock with try-finally guarantee
  • Zero breaking changes

Impact

  • ✅ Fixes "Invalid state" regression from v2.8.0
  • ✅ Maintains MRRT performance improvements
  • ✅ Affects: useRefreshTokens: false or useRefreshTokensFallback: true scenarios

Testing

Tested with multiple parallel getTokenSilently() calls for different audiences - no "Invalid state" errors observed.

@yogeshchoudhary147 yogeshchoudhary147 requested a review from a team as a code owner January 13, 2026 04:28
@yogeshchoudhary147 yogeshchoudhary147 force-pushed the fix/iframe-race-condition-two-tier-locking branch from 823afc9 to d43d034 Compare January 13, 2026 04:32
@yogeshchoudhary147 yogeshchoudhary147 force-pushed the fix/iframe-race-condition-two-tier-locking branch 6 times, most recently from 6086654 to 96d32cb Compare January 16, 2026 04:19
- Add global iframe lock to serialize iframe authorization requests
- Keep per-audience locking for refresh token flows (preserves MRRT performance)
- Fixes 'Invalid state' errors when multiple audiences requested in parallel
- Resolves regression introduced in v2.8.0 by PR #1408

Two-tier locking strategy:
- Outer lock (per-audience): Prevents duplicate calls for same audience
- Inner lock (global iframe): Prevents Auth0 session state conflicts

Refresh token flows bypass the inner lock and remain fully parallel.
Iframe flows acquire both locks to ensure correctness.
- Add new test suite for two-tier locking behavior
- Test that iframe flows acquire both per-audience and iframe locks
- Test that refresh token flows only acquire per-audience lock
- Test iframe lock release on errors and fallback scenarios
- Update 'should retry acquiring a lock' test to account for iframe lock
- Skip 4 tests that relied on parallel iframe execution (intentionally changed behavior)
- Update 'should add pagehide event listener' test for new serialization behavior

All 678 tests pass (5 skipped by design)
- Unskipped 4 tests that were overly conservative
- Updated 'should handle errors' test to verify lock release on errors
- Updated 'serialize iframe calls with different audiences' test
- Updated 'simultaneous calls with same audience' test (still deduplicates via per-audience lock)
- Updated 'release lock correctly' test for subsequent calls
- Only 1 test remains skipped (pagehide with truly concurrent locks)

All 678 tests pass (677 active + 1 skipped)
- Add GET_TOKEN_FROM_IFRAME_LOCK_KEY constant
- Expand comments explaining iframe serialization necessity

Addresses feedback from @frederikprijck
Use inline lock acquisition with try-finally pattern to match the more
robust approach used in _getTokenSilently().
@yogeshchoudhary147 yogeshchoudhary147 force-pushed the fix/iframe-race-condition-two-tier-locking branch from 96d32cb to adc9ab0 Compare January 16, 2026 04:20
@yogeshchoudhary147 yogeshchoudhary147 merged commit 8b98fe9 into main Jan 16, 2026
13 checks passed
@yogeshchoudhary147 yogeshchoudhary147 deleted the fix/iframe-race-condition-two-tier-locking branch January 16, 2026 07:36
yogeshchoudhary147 added a commit that referenced this pull request Jan 16, 2026
**Fixed**
- fix: add two-tier locking to prevent iframe race conditions causing
"Invalid state" errors
[\#1505](#1505)
([yogeshchoudhary147](https://github.com/yogeshchoudhary147))
- fix: handle undefined value when finding MRRT refresh token
[\#1508](#1508)
([mogzol](https://github.com/mogzol))
- fix: update refresh token in all cache entries on rotation
[\#1503](#1503)
([gyaneshgouraw-okta](https://github.com/gyaneshgouraw-okta))
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.

4 participants