Skip to content

fix(clerk-js): Prevent infinite polling loop on invalid dev browser token#7951

Merged
brkalow merged 2 commits intomainfrom
brkalow/fix-polling-loop
Feb 27, 2026
Merged

fix(clerk-js): Prevent infinite polling loop on invalid dev browser token#7951
brkalow merged 2 commits intomainfrom
brkalow/fix-polling-loop

Conversation

@brkalow
Copy link
Member

@brkalow brkalow commented Feb 27, 2026

Description

Fixes infinite polling loop that occurs when the __clerk_db_jwt dev browser token becomes invalid during runtime. When the token refresh request returns dev_browser_unauthenticated, it was previously treated as a general 401 error, triggering handleUnauthenticated which calls Client.fetch, creating an infinite recursion loop until rate-limited.

The fix intercepts dev_browser_unauthenticated errors in _baseFetch and calls __internal_handleUnauthenticatedDevBrowser to refresh the dev browser token instead of entering the session-level sign-out flow.

Includes an integration test that verifies dev browser refresh occurs without excessive /v1/client requests (which would indicate the infinite loop).

Checklist

  • pnpm test runs as expected (all unit tests pass, integration test passes)
  • pnpm build runs as expected
  • Integration test validates the fix

Type of change

  • 🐛 Bug fix

Summary by CodeRabbit

  • Bug Fixes
    • Prevents infinite polling loops when a development-session authentication error occurs, keeping request rates bounded.
    • Ensures the dev-session token is reset on specific unauthenticated errors to stop runaway requests.
    • Improves resiliency of token refresh and session handling during development polling.

…s invalid

When the __clerk_db_jwt dev browser token becomes invalid during runtime, the token
refresh request returns dev_browser_unauthenticated. Previously, this error was
treated as a general 401, triggering handleUnauthenticated which calls Client.fetch,
which also fails with 401, creating an infinite recursion loop until rate-limited.

This fix intercepts dev_browser_unauthenticated errors at the _baseFetch level and
calls __internal_handleUnauthenticatedDevBrowser to refresh the dev browser token
instead of entering the session-level sign-out flow. The poller then retries with
the fresh dev browser token on its next tick.

Also adds an integration test that verifies dev browser refresh occurs without
excessive /v1/client requests (the sign of the infinite loop).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Feb 27, 2026

🦋 Changeset detected

Latest commit: 3dbaee9

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

This PR includes changesets to release 3 packages
Name Type
@clerk/clerk-js Patch
@clerk/chrome-extension Patch
@clerk/expo Patch

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

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Feb 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 27, 2026 6:29pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c5129b5 and 3dbaee9.

📒 Files selected for processing (1)
  • .changeset/fix-dev-browser-polling-loop.md

📝 Walkthrough

Walkthrough

Adds handling for dev_browser_unauthenticated responses: a test helper that crafts 401 responses with code dev_browser_unauthenticated and a test ensuring polling does not enter an infinite loop. Introduces Clerk.__internal_handleUnauthenticatedDevBrowser() which delegates to the internal AuthCookieService's handleUnauthenticatedDevBrowser(). Refactors 401 handling in Base.ts to call the dev-browser reset path when the error code is dev_browser_unauthenticated. A changeset for a patch release is included.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: preventing an infinite polling loop caused by invalid dev browser tokens, which aligns perfectly with the PR's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 27, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7951

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7951

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7951

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7951

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7951

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7951

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7951

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7951

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7951

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7951

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7951

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7951

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7951

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7951

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7951

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7951

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7951

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7951

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7951

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7951

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7951

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7951

commit: 3dbaee9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@brkalow brkalow merged commit b7b00ac into main Feb 27, 2026
41 checks passed
@brkalow brkalow deleted the brkalow/fix-polling-loop branch February 27, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants