Skip to content

fix(expo): clear JWT from SecureStore on sign-out to prevent stale session errors#8154

Draft
chriscanin wants to merge 2 commits intomainfrom
chris/fix-clear-jwt-on-signout
Draft

fix(expo): clear JWT from SecureStore on sign-out to prevent stale session errors#8154
chriscanin wants to merge 2 commits intomainfrom
chris/fix-clear-jwt-on-signout

Conversation

@chriscanin
Copy link
Member

@chriscanin chriscanin commented Mar 23, 2026

Summary

Fixes "session_exists" / "already signed in" errors when users try to sign in again after signing out via native components (<AuthView />, <UserButton />).

When signing out, clerk.signOut() clears the Clerk JS SDK state but does NOT clear the JWT stored in expo-secure-store. On the next sign-in attempt, the stale JWT is sent with the FAPI request, causing the server to reject it with "session_exists" because it sees an active session.

The fix explicitly deletes the JWT from SecureStore before calling clerk.signOut() in both:

  • ClerkProvider.tsx (native auth state sync for signedOut events)
  • UserButton.tsx (sign-out after profile modal closes)

Reported by

Test plan

  • Sign in via <AuthView />, sign out, sign in again (no "already signed in" error)
  • Sign in via <UserButton /> profile, sign out, sign in again (no error)
  • Verify JWT is cleared from SecureStore after sign-out

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where signing out through native components would not properly clear authentication state, preventing re-sign-in errors (e.g., "already signed in" or "session exists" messages).

…ssion errors

When signing out via native components (AuthView, UserButton), the JWT
in SecureStore was not cleared. On the next sign-in attempt, the stale
JWT caused 'session_exists' / 'already signed in' errors because FAPI
still saw the old session. Now explicitly deletes the JWT before calling
clerk.signOut() in both the ClerkProvider native auth sync and the
UserButton sign-out flow.
@vercel
Copy link

vercel bot commented Mar 23, 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 Mar 23, 2026 5:56pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Mar 23, 2026

🦋 Changeset detected

Latest commit: eb4c7c9

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 23, 2026

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: eb4c7c9

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

This changeset adds JWT cleanup logic to the @clerk/expo package. The UserButton component now deletes the stored Clerk client JWT from SecureStore before invoking clerk.signOut. Similarly, ClerkProvider deletes the JWT from SecureStore when receiving a native signedOut event before calling clerkInstance.signOut(). A changeset metadata file documents this patch-level fix. All SecureStore deletion failures are caught and ignored to prevent blocking sign-out operations.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: clearing JWT from SecureStore on sign-out to prevent stale session errors, which matches the core fix applied across UserButton.tsx and ClerkProvider.tsx.

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


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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/expo/src/provider/ClerkProvider.tsx`:
- Around line 258-261: Add regression tests that exercise sign-in → sign-out →
sign-in flows to ensure the JWT cleanup prevents "session_exists"/"already
signed in" errors: create tests for both sign-out paths (calling
clerkInstance.signOut and the native UserButton sign-out flow from
packages/expo/src/native/UserButton.tsx), mock SecureStore.deleteItemAsync and
CLERK_CLIENT_JWT_KEY behavior, simulate an initial sign-in storing a JWT, invoke
the sign-out flow and verify SecureStore.deleteItemAsync was called and the
token removed, then simulate a subsequent sign-in and assert no
"session_exists"/"already signed in" error occurs; use mocks for clerkInstance
methods and SecureStore so tests assert token cleanup and successful re-sign-in.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 340a38fd-a23a-4960-ba42-4abf5dcab09d

📥 Commits

Reviewing files that changed from the base of the PR and between cabbe3a and eb4c7c9.

📒 Files selected for processing (3)
  • .changeset/fix-clear-jwt-on-signout.md
  • packages/expo/src/native/UserButton.tsx
  • packages/expo/src/provider/ClerkProvider.tsx

Comment on lines +258 to 261
// Clear the JWT from SecureStore before signing out to prevent
// "session_exists" / "already signed in" errors on the next sign-in attempt.
await SecureStore.deleteItemAsync(CLERK_CLIENT_JWT_KEY).catch(() => {});
await clerkInstance.signOut();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add regression coverage for JWT cleanup sign-out flows before merge.

Line 258 changes auth-state behavior, and the PR also changes packages/expo/src/native/UserButton.tsx (Line 160), but no tests were added/updated. Please add regression tests that cover: sign-in → sign-out via both native flows → sign-in again, and assert no "session_exists" / "already signed in" failure plus token cleanup.

As per coding guidelines: "If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/expo/src/provider/ClerkProvider.tsx` around lines 258 - 261, Add
regression tests that exercise sign-in → sign-out → sign-in flows to ensure the
JWT cleanup prevents "session_exists"/"already signed in" errors: create tests
for both sign-out paths (calling clerkInstance.signOut and the native UserButton
sign-out flow from packages/expo/src/native/UserButton.tsx), mock
SecureStore.deleteItemAsync and CLERK_CLIENT_JWT_KEY behavior, simulate an
initial sign-in storing a JWT, invoke the sign-out flow and verify
SecureStore.deleteItemAsync was called and the token removed, then simulate a
subsequent sign-in and assert no "session_exists"/"already signed in" error
occurs; use mocks for clerkInstance methods and SecureStore so tests assert
token cleanup and successful re-sign-in.

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.

1 participant