From ff8e1dd22a47350a0d20c157610b7ae203611950 Mon Sep 17 00:00:00 2001 From: ChrisCanin Date: Mon, 23 Mar 2026 10:55:32 -0700 Subject: [PATCH 1/2] fix(expo): clear JWT from SecureStore on sign-out to prevent stale session 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. --- packages/expo/src/native/UserButton.tsx | 5 +++++ packages/expo/src/provider/ClerkProvider.tsx | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/packages/expo/src/native/UserButton.tsx b/packages/expo/src/native/UserButton.tsx index 045d3027080..5f972f8f23f 100644 --- a/packages/expo/src/native/UserButton.tsx +++ b/packages/expo/src/native/UserButton.tsx @@ -1,7 +1,9 @@ import { useClerk, useUser } from '@clerk/react'; +import * as SecureStore from 'expo-secure-store'; import { useEffect, useRef, useState } from 'react'; import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { CLERK_CLIENT_JWT_KEY } from '../constants'; import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module'; // Raw result from native module (may vary by platform) @@ -155,6 +157,9 @@ export function UserButton(_props: UserButtonProps) { } } + // Clear stale JWT from SecureStore to prevent "already signed in" errors + await SecureStore.deleteItemAsync(CLERK_CLIENT_JWT_KEY).catch(() => {}); + // Sign out from JS SDK to update isSignedIn state if (clerk?.signOut) { try { diff --git a/packages/expo/src/provider/ClerkProvider.tsx b/packages/expo/src/provider/ClerkProvider.tsx index 153cbbef18e..69ec965f3ac 100644 --- a/packages/expo/src/provider/ClerkProvider.tsx +++ b/packages/expo/src/provider/ClerkProvider.tsx @@ -10,6 +10,7 @@ import { CLERK_CLIENT_JWT_KEY } from '../constants'; import { useNativeAuthEvents } from '../hooks/useNativeAuthEvents'; import NativeClerkModule from '../specs/NativeClerkModule'; import { tokenCache as defaultTokenCache } from '../token-cache'; +import * as SecureStore from 'expo-secure-store'; import { isNative, isWeb } from '../utils/runtime'; import { getClerkInstance } from './singleton'; import type { BuildClerkOptions } from './singleton/types'; @@ -254,6 +255,9 @@ export function ClerkProvider(props: ClerkProviderProps {}); await clerkInstance.signOut(); } } catch (error) { From eb4c7c903e31fd4c7a35b26b8291954485c9f9da Mon Sep 17 00:00:00 2001 From: ChrisCanin Date: Mon, 23 Mar 2026 10:55:45 -0700 Subject: [PATCH 2/2] chore: add changeset --- .changeset/fix-clear-jwt-on-signout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-clear-jwt-on-signout.md diff --git a/.changeset/fix-clear-jwt-on-signout.md b/.changeset/fix-clear-jwt-on-signout.md new file mode 100644 index 00000000000..8be2e8ff496 --- /dev/null +++ b/.changeset/fix-clear-jwt-on-signout.md @@ -0,0 +1,5 @@ +--- +'@clerk/expo': patch +--- + +Clear JWT from SecureStore when signing out via native components (AuthView, UserButton) to prevent "session_exists" / "already signed in" errors on subsequent sign-in attempts.