Skip to content

fix(nextjs): share the initialization between concurrent cold-start requests - #551

Open
DonOmalVindula wants to merge 1 commit into
asgardeo:mainfrom
DonOmalVindula:fix/nextjs-init-race
Open

fix(nextjs): share the initialization between concurrent cold-start requests#551
DonOmalVindula wants to merge 1 commit into
asgardeo:mainfrom
DonOmalVindula:fix/nextjs-init-race

Conversation

@DonOmalVindula

Copy link
Copy Markdown
Contributor

Problem

AsgardeoNextClient is a process-wide singleton, and initialize() set isInitialized = true before its first await (getClientOrigin()). On a cold start, requests arriving in parallel (a page request plus RSC prefetches is enough) hit this window:

  • the second request's initialize() returned early because the flag was already set,
  • AsgardeoServerProvider then called getConfiguration() while the legacy client had no authCore yet, which threw Cannot read properties of undefined (reading 'getConfigData') and turned into a 500 for that request.

A failed initialization (for example headers() throwing outside a request scope) had the same shape: the flag stayed true, the legacy client stayed uninitialized, and every later call failed until the process restarted.

Fix

  • initialize() keeps the in-flight initialization promise; concurrent callers share it, isInitialized is only set once it succeeds, and a failed attempt is cleared so the next request retries.
  • ensureInitialized() waits for an initialization in progress instead of throwing.

Testing

  • New unit tests cover concurrent callers sharing one initialization, callers waiting on the in-flight initialization, a failed attempt being retried, and sequential calls initializing once.
  • pnpm lint, pnpm vitest run (64 tests) and tsc --noEmit for @asgardeo/nextjs.

Changeset included (@asgardeo/nextjs patch).

🤖 Generated with Claude Code

…equests

AsgardeoNextClient.initialize() marked the singleton as initialized before its
first await, so a second request arriving while the first was still resolving
the app origin proceeded with an uninitialized legacy client and failed with
"Cannot read properties of undefined (reading 'getConfigData')". A failed
initialization also left the client permanently flagged as initialized.

Callers now await the initialization in progress, the flag is only set once
it succeeds, and a failed attempt is retried by the next call.
ensureInitialized() waits for an in-flight initialization instead of throwing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 9d43b7ca-2fe3-48a7-ab1c-01a3b7dec241

📥 Commits

Reviewing files that changed from the base of the PR and between 409ebae and df1c6f6.

📒 Files selected for processing (3)
  • .changeset/nextjs-initialization-race.md
  • packages/nextjs/src/AsgardeoNextClient.ts
  • packages/nextjs/src/__tests__/AsgardeoNextClient.initialize.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@asgardeo-github-bot

Copy link
Copy Markdown

🦋 Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

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.

2 participants