Skip to content

fix(expo): refresh native after a JS change that lands during a native pull - #10431

Merged
wobsoriano merged 3 commits into
mainfrom
rob/mobile-670-flaky-test-expo-native-user-sync-after-sign-in
Oct 26, 2026
Merged

wobsoriano merged 3 commits into
mainfrom
rob/mobile-670-flaky-test-expo-native-user-sync-after-sign-in

Conversation

@wobsoriano

@wobsoriano wobsoriano commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Description

Fixes MOBILE-670. JS sometimes signed in with a ticket at launch while the native UserButton stayed empty.

Cause

At launch, native emits clerkNativeClientInvalidated once its first client load lands, and JS starts a pull. When the pull ended, fromNative recorded the current JS fingerprint as already known to native. If the ticket sign-in finished while the pull was in flight, that fingerprint already contained the new session. The next toNative saw an equal fingerprint and skipped refreshClient(), so native never got the session.

Fix

fromNative no longer sets lastFingerprint. Only toNative records it, right before it refreshes native. A native-originated change now costs one extra native client refresh, which the "settles a native change without an echo loop" test now expects. JS cannot tell which server state native last fetched, so avoiding that refresh without a race would need a native contract change.

Verification

The new behavior test signs JS in while a native pull is in flight. It fails on main (JS on sess_4, native stuck on sess_3) and passes with the fix.

To force the race on devices, two throwaway branches added a 2s delay before the pull plus log markers, and ran Expo E2E with workflow_dispatch.

Build Android iOS
main with the delay 1 failed (Open user profile not found) 4 failed (clerk.userButton.profile not found)
This branch with the delay 15 of 15 passed 16 of 16 passed

The Android app log of a failed launch shows the sequence. The pull starts at 52.521, the ticket sign-in lands at 53.329, then the pull ends and both toNative calls skip.

18:36:52.521 [mobile-670] pull start
18:36:53.329 [verify] {"signedIn":true,"userId":"user_3LFB...","sessionId":"sess_3LFB...", ...}
18:36:54.731 [mobile-670] pull end ["client_3LFB...","sess_3LFB...",...]
18:36:54.731 [mobile-670] toNative skip ["client_3LFB...","sess_3LFB...",...]
18:36:54.731 [mobile-670] toNative skip ["client_3LFB...","sess_3LFB...",...]

The iOS run linked in the ticket (10/23) is a different failure. Its home showed Signed out at the failure, and it predates #10407, which fixed that symptom.

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:

@vercel

vercel Bot commented Oct 26, 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 26, 2026 6:59pm UTC
swingset Ready Ready Preview Oct 26, 2026 6:59pm UTC

Request Review

@changeset-bot

changeset-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 774d3d0

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

This PR includes changesets to release 1 package
Name Type
@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

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 3fa3ad1 and 774d3d0.

Files selected for processing: 3
  • .changeset/expo-refresh-native-after-pull.md
  • packages/expo/src/provider/__tests__/nativeClientSyncBehavior/nativeClientSync.behavior.test.tsx
  • packages/expo/src/provider/nativeClientSync.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

The native-to-JavaScript sync no longer records the fingerprint after a pull. Tests now expect one native client refresh and cover a JavaScript sign-in that occurs during a native-change refetch, verifying that JavaScript and native select the same session. A changeset declares a patch release for @clerk/expo.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Severity of issue fixed: Medium

Possibly related PRs

  • clerk/javascript#10407: Updates the same native sync engine for signed-in clients during device-token rotation races.
  • clerk/javascript#10397: Addresses Expo launch-ticket sign-in timing before JavaScript ticket sign-in.

Suggested reviewers: mikepitre

Merge Risk: Minimal · up to 774d3

No concrete merge-blocking risk is established by the reviewed change.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title names the change: a native refresh is added after a JS change that lands during a native pull. It matches the fix described in the raw summary (fromNative no longer records the fingerprint; …
Description check Passed The description states the bug (JS signs in with a ticket at launch while native UserButton stays empty), the cause (fromNative records the JS fingerprint after a native pull, so toNative skips refres…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 …
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: Title check

Explanation

The title names the change: a native refresh is added after a JS change that lands during a native pull. It matches the fix described in the raw summary (fromNative no longer records the fingerprint; toNative records it before refreshing native) and the stated bug in MOBILE-670. It is specific and scoped to @clerk/expo, so it describes the main change.

Full details: Description check

Explanation

The description states the bug (JS signs in with a ticket at launch while native UserButton stays empty), the cause (fromNative records the JS fingerprint after a native pull, so toNative skips refreshClient()), the fix (fromNative no longer sets lastFingerprint; toNative records it before refreshing), the updated test expectation, and device verification. It relates directly to the changeset, the test file, and nativeClientSync.ts.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 unsupported.)

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Linked repositories: Some configured repositories could not be included in this review. Cross-repository analysis may be incomplete. Please check linked-repository access and settings.

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

@pkg-pr-new

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

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-biometrics

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

@clerk/expo-google-signin

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

@clerk/expo-native-components

npm i https://pkg.pr.new/@clerk/expo-native-components@10431

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/mosaic

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 774d3d0

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-10-26T19:00:11.987Z

Summary

Metric Count
Packages analyzed 20
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 774d3d0.

@wobsoriano
wobsoriano requested a review from mikepitre October 26, 2026 19:26
Comment thread packages/expo/src/provider/nativeClientSync.ts

@mikepitre mikepitre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good. Fixes the race the expo e2e runs were hitting, and the regression test fails on main and passes here.

@wobsoriano
wobsoriano merged commit 8f9f481 into main Oct 26, 2026
62 checks passed
@wobsoriano
wobsoriano deleted the rob/mobile-670-flaky-test-expo-native-user-sync-after-sign-in branch October 26, 2026 20:57

This branch was successfully deployed

2 active deployments
Preview – swingset — 774d3d05 Deployed Oct 26, 2026 by vercel[bot]
Preview – clerk-js-sandbox — 774d3d05 Deployed Oct 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants