clerk / clerk/javascript

`signIn.reset()` / `client.resetSignIn()` don't propagate a fresh empty SignIn to the Future `useSignIn()` hook, so `sso()` after reset reuses the stale resource and never navigates

Open
#9,006 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug clerk-js confirmed core-3
Dominant language
TypeScript
Stars
1.8k
Forks
472
Avg merge
2d 11h
Merged PRs (30d)
189

Description

Preliminary Checks
Reproduction

https://github.com/clerk/javascript

Publishable key

pk_test_1234

Description

Summary

I'm using the Future custom-flow hooks (useSignIn() from @clerk/nextjs, not /legacy). When I reset an in-progress sign-in, the reset doesn't propagate a new empty SignInFuture resource to the hook's signIn. The only way I've found to get the live post-reset resource at call-time is the internal clerk.client.signIn.__internal_future. Your support team confirmed this: "our existing reset pathway doesn't result in the propagation of a new empty SignIn for the new hooks."

Environment

  • @clerk/nextjs@7.3.4
  • @clerk/shared@4.11.0
  • clerk-js@6.11.0
  • Default import: import { useSignIn } from '@clerk/nextjs' (Future API, not /legacy)

Reproduction

Custom SSO flow built on useSignIn():

  1. Leave an in-progress SignIn. Easiest way is to start a discoverable passkey (signIn.passkey({ flow: 'discoverable' })) and then dismiss the WebAuthn prompt, which persists a signIn with an id.
  2. In a single click handler, call await signIn.reset() (or clerk.client.resetSignIn()).
  3. Immediately call await signIn.sso({ strategy: 'oauth_google', redirectUrl, redirectCallbackUrl }).

Expected

sso() starts a fresh OAuth attempt and navigates to the provider.

Actual

sso() PATCH-continues the stale (pre-reset) SignIn and resolves without navigating, so the SSO button just hangs. The signIn reference captured in my handler's closure is the pre-reset one, and since the SignInFuture resource has an intentionally unstable identity and reset doesn't refresh the hook's value, the closure can never see the new resource within the same handler. A memo dep array only affects future invocations, not the one that's already running.

Workaround

I read the live resource at call-time from the internal field:

if (clerk.client?.signIn.id) clerk.client.resetSignIn();
const resource = clerk.client?.signIn.__internal_future ?? signIn;
await resource.sso({ ... });

This leans on __internal_future, which is internal and can break between minor versions, for what's otherwise a completely ordinary flow (reset a stale sign-in, then start SSO).

Suggested fixes (any one of these would let me drop __internal_future)

  • reset() resolves with the fresh SignInFuture resource, or
  • a public accessor for the live resource (something like clerk.client.signInFuture), or
  • reset() propagates a new empty SignIn to the useSignIn() hook so calling sso() on the hook's signIn works after a reset.
Environment
I was told by support I didn't need to provide any of this:
> Thanks for the info! I think the best way to follow this would be to file an issue on our GitHub repo for the JavaScript SDKs https://github.com/clerk/javascript. A minimal reproduction would be incredible if you can toss one together, but totally fine if not. I took a quick look and I do think you're right on the money that our existing reset pathway doesn't result in the propagation of a new empty SignIn for the new hooks.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Future useSignIn() entry point and the signIn.reset()/clerk.client.resetSignIn() path; reproduce the passkey-dismissal flow, then immediately call sso(). Done means reset exposes or propagates a fresh empty SignInFuture so the subsequent sso() starts OAuth and navigates without relying on __internal_future.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, typescript
Domain
authentication
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.