Skip to content

fix(ui): sign in a returning user after a sign-up verification challenge - #10158

Open
mwickett wants to merge 2 commits into
mainfrom
mwickett/prot-1201-prebuilt-google-sign-up-loses-the-existing-account-transfer
Open

mwickett wants to merge 2 commits into
mainfrom
mwickett/prot-1201-prebuilt-google-sign-up-loses-the-existing-account-transfer

Conversation

@mwickett

@mwickett mwickett commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Description

A returning user who picks a social provider on the prebuilt <SignUp /> is normally signed in to their existing account. The OAuth callback sees the transferable / external_account_exists verification on the sign-up and completes it with signIn.create({ transfer: true }).

When that sign-up comes back gated by a verification challenge, the callback routes to the challenge card before it reaches the transfer. Once the challenge clears, SignUpProtectCheck routes with completeSignUpFlow, which has no transfer step. It sees email_address and password still missing and sends the user to "Fill in missing fields", where they are asked to create a new account.

This is the mirror image of #9497, which resumed a challenged sign-in that has to become a sign-up. The sign-up card now does the same in the other direction: when the resolved sign-up is still an existing-account transfer, it hands back to the callback router through __internal_resumeAfterProtectCheck, which skips the challenge short-circuits and runs the transfer.

  • Each route passes the card the same callback params as its sibling sso-callback route (buildSignUpOAuthCallbackParams in <SignUp />, buildCombinedFlowOAuthCallbackParams under the combined flow's create/), so relative sign-in step URLs resolve from the right depth.
  • The continue/protect-check mounts are not given the params. They are reached from the Continue form rather than from a callback, and keep routing as before.
  • A chained challenge still runs first, and a completed sign-up is still finalized.
  • If the continuation fails after the transfer has committed, "Try again" goes back to the callback router, which routes on the sign-in the transfer created.
  • @clerk/ui can load against a clerk-js that predates __internal_resumeAfterProtectCheck, so the call is feature-detected and falls back to the previous routing.

There are no clerk-js source changes. The additions to clerk.test.ts pin the router behavior the card now relies on.

To try it: on an instance that challenges every sign-up, use <SignUp /> with Google and an account that already exists. After the challenge you should be signed in to that account instead of landing on "Fill in missing fields".

Fixes PROT-1201

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

When a prebuilt sign-up returns from a social provider for an account that
already exists, the OAuth callback transfers it to a sign-in. A verification
challenge interrupts the callback before that transfer runs, and the
challenge card then routed with `completeSignUpFlow`, which has no transfer
step, so the user landed on "Fill in missing fields".

The card now hands back to the callback router once the challenge clears,
the same way the sign-in card does for a sign-in that becomes a sign-up.
@changeset-bot

changeset-bot Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 52c8eec

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

This PR includes changesets to release 2 packages
Name Type
@clerk/ui Patch
@clerk/chrome-extension 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

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
clerk-js-sandbox Ready Ready Preview Oct 8, 2026 11:50pm UTC
swingset Ready Ready Preview Oct 8, 2026 11:50pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: 7093edaa-89cc-4dc8-b5b6-7b3fa417a357
📥 Commits

Reviewing files that changed from the base of the PR and between 7307406 and 52c8eec.

📒 Files selected for processing (8)
  • .changeset/sign-up-existing-account-after-challenge.md
  • packages/clerk-js/src/core/__tests__/clerk.test.ts
  • packages/ui/src/components/SignIn/__tests__/SignInCombinedFlowSSOCallback.test.tsx
  • packages/ui/src/components/SignIn/index.tsx
  • packages/ui/src/components/SignUp/SignUpProtectCheck.tsx
  • packages/ui/src/components/SignUp/__tests__/SignUpProtectCheck.test.tsx
  • packages/ui/src/components/SignUp/index.tsx
  • packages/ui/src/components/SignUp/util.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. 9 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.


📝 Walkthrough

Walkthrough

The sign-up Protect Check flow now receives OAuth callback parameters and resumes callback handling when a cleared challenge reveals a transferable account that already belongs to a user. Tests cover challenge routing, transfer to sign-in, session activation, retries, and ordinary sign-up completion.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: zourzouvillys

Merge Risk: ⚪ Minimal · up to 52c8e

The returning-user challenge flow has no identified issue requiring a fix before merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main UI fix: signing in a returning user after a sign-up verification challenge.
Description check Passed The description directly explains the affected sign-up flow, the callback-router fix, compatibility behavior, tests, and validation steps.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@pkg-pr-new

pkg-pr-new Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@10158

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@10158

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@10158

@clerk/expo

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

@clerk/expo-biometrics

npm i https://pkg.pr.new/@clerk/expo-biometrics@10158

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@10158

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/mosaic

npm i https://pkg.pr.new/@clerk/mosaic@10158

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 52c8eec

Once the transfer commits, the client no longer holds a sign-up that looks
like a transfer. If a later step failed, "Try again" re-read that sign-up,
fell through to `completeSignUpFlow` and did nothing. The card now
remembers that it handed off, so a retry goes back to the router, which
routes on the sign-in the transfer created.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T00:12:41.259243Z 52c8eec Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52c8eeccd6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (
oauthCallbackParams &&
typeof __internal_resumeAfterProtectCheck === 'function' &&
(didResumeOAuthCallbackRef.current || isSignUpPendingOAuthTransfer(updatedSignUp))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve OAuth-transfer intent across challenge submission

When the gated sign-up initially carries external_account_exists but submitProtectCheck returns a resource without that verification marker, this first-run predicate is false because didResumeOAuthCallbackRef is also still false. SignUp.fromJSON replaces verifications wholesale, so the marker is not guaranteed to survive the challenge response; the code then falls through to completeSignUpFlow and sends the returning user to fill the missing email/password fields—the original regression. Snapshot the transfer state before submitting, as SignInProtectCheck already does with startedAsOAuthTransfer, and include that snapshot in this condition.

AGENTS.md reference: AGENTS.md:L12-L12

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-10-09T00:13:13.312Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 0
🔴 Breaking changes 0
🟡 Non-breaking changes 0
🟢 Additions 0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 52c8eec.

This branch was successfully deployed

2 active deployments
Preview – swingset — 52c8eecc Deployed Oct 8, 2026 by vercel[bot]
Preview – clerk-js-sandbox — 52c8eecc Deployed Oct 8, 2026 by vercel[bot]
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.

1 participant