From 9cd68a6b83af8b79869bd59202085bc03cfd914a Mon Sep 17 00:00:00 2001 From: FranKaddour Date: Wed, 1 Jul 2026 10:16:24 -0300 Subject: [PATCH] fix(js): preserve SignUpFuture reference across SSO-to-sign-up transition When an SSO sign-in transitions to a sign-up flow (e.g. account does not exist, legal acceptance required), Client.fromJSON created a brand-new SignUp instance because the existing one had no id and the incoming data did. The old SignUpFuture held by useSignUp() hooks pointed at the stale id-less instance, so subsequent update() calls sent PATCH to /client/sign_ups instead of /client/sign_ups/{id} and received a 405. Fix: update the existing SignUp in-place (via __internal_updateFromJSON) when it has no id yet, which preserves the SignUpFuture reference and ensures hooks see the correct id after the transition. Fixes #8338 --- .changeset/fix-signup-future-sso-transfer-stale-ref.md | 5 +++++ packages/clerk-js/src/core/resources/Client.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-signup-future-sso-transfer-stale-ref.md diff --git a/.changeset/fix-signup-future-sso-transfer-stale-ref.md b/.changeset/fix-signup-future-sso-transfer-stale-ref.md new file mode 100644 index 00000000000..1ac84a8a110 --- /dev/null +++ b/.changeset/fix-signup-future-sso-transfer-stale-ref.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Fix `signUp.update()` sending a PATCH request to `/client/sign_ups` instead of `/client/sign_ups/{id}` after an SSO sign-in transitions to a sign-up flow (e.g. when legal acceptance is required). The `SignUpFuture` reference held by hooks is now preserved across the transition and reflects the correct sign-up id. diff --git a/packages/clerk-js/src/core/resources/Client.ts b/packages/clerk-js/src/core/resources/Client.ts index 6b690c7261c..b06ac0b80ae 100644 --- a/packages/clerk-js/src/core/resources/Client.ts +++ b/packages/clerk-js/src/core/resources/Client.ts @@ -143,7 +143,11 @@ export class Client extends BaseResource implements ClientResource { this.id = data.id; this.sessions = (data.sessions || []).map(s => new Session(s)); - if (data.sign_up && this.signUp instanceof SignUp && this.signUp.id === data.sign_up.id) { + if (data.sign_up && this.signUp instanceof SignUp && (this.signUp.id === data.sign_up.id || !this.signUp.id)) { + // Update in-place when ids match OR when the existing signUp has no id yet + // (e.g. an SSO sign-in that transitions to a sign-up flow). Reusing the same + // SignUp instance preserves any SignUpFuture references held by hooks so they + // remain valid and reflect the correct id after the transition. this.signUp.__internal_updateFromJSON(data.sign_up); } else { this.signUp = new SignUp(data.sign_up);