[@clerk/clerk-js] <SignUp/> sends 2 verification code emails per sign-up: both POST /sign_ups and POST /prepare_verification trigger email send (Flutter analog #117)
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 52/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- react, typescript
- Área
- api, authentication, frontend
Línea de trabajo
Comienza con el flujo precompilado y las llamadas signUp.create y prepareEmailAddressVerification descritas en el issue; reprodúcelo con pnpm --filter web build && pnpm --filter web preview e inspecciona el panel Network. Se considera terminado cuando un único envío de registro produce exactamente un correo electrónico de verificación sin requerir un flujo useSignUp() personalizado.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Preflight
- I have looked into the Readme, Contributing docs and existing issues
- I have reviewed the documentation
Description
The prebuilt <SignUp/> widget from @clerk/react@6.4.2 sends two verification-code emails for a single sign-up submission. The Network panel shows the widget makes two POST requests during one submit, and both server endpoints trigger a verification email send:
POST /v1/client/sign_ups?__clerk_api_version=2025-11-10—signUp.create({ emailAddress, password })POST /v1/client/sign_ups/<id>/prepare_verification?__clerk_api_version=2025-11-10—signUp.prepareEmailAddressVerification({ strategy: 'email_code' })
The user receives two emails with different codes; the first one is invalidated by the second.
Why this is a real bug (not a duplicate of #887)
This is the prebuilt-widget analog of the documented behavior in #887 (closed 2023-03-03), where Clerk contributor @gkats explained:
the
signIn.create()method will also prepare a verification under the hood when called with a strategy such as "email_code". That's why you get two codes. The first one comes fromsignIn.create()and becomes invalid as soon as the second one is generated. When you callsignIn.create()with a "phone_code", "email_code" or "email_link" strategy you don't need to also prepare the verification afterwards.
That explanation applies symmetrically to signUp.create(): when the application's configured strategy is email_code (Dashboard → User & Authentication → Email, Phone, Username → Email address → ✅ Email verification code), signUp.create() auto-prepares a verification on the server side, and the widget's subsequent explicit prepareEmailAddressVerification call generates a second code.
The #887 resolution was a workaround for custom sign-in flows: omit the strategy from signIn.create(), then call prepareFirstFactor() manually. Users of the prebuilt <SignUp/> widget cannot apply this workaround — the widget controls both calls internally. Rebuilding sign-up as a custom useSignUp() flow defeats the purpose of the prebuilt component.
So either:
- (a) The prebuilt
<SignUp/>widget should detect thatsignUp.create()already initiated verification (returned status with the right verification primed) and skip the redundantprepareEmailAddressVerificationcall; OR - (b)
signUp.create()should NOT auto-prepare a verification (the widget should be the sole driver of when verification preparation happens, matching what the workaround in #887 recommends for custom flows).
For comparison, the same root-cause shape was filed against the Flutter SDK and is the documented behavior there too: clerk/clerk-sdk-flutter#117 (createSignUp + follow-up triggering two emails).
Reproduction
Minimal repro is the prebuilt <SignUp/> widget with password + email_code strategy. No custom code, no useSignUp() flow.
// main.tsx
import { ClerkProvider } from "@clerk/react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ClerkProvider publishableKey={CLERK_KEY}>
<App />
</ClerkProvider>
</StrictMode>
);
// sign-up.tsx
import { SignUp } from "@clerk/react";
export function SignUpPage() {
return (
<SignUp
routing="path"
path="/sign-up"
signInUrl="/sign-in"
/>
);
}
Clerk Dashboard → User & Authentication → Email, Phone, Username → Email address → Verification methods:
- ✅ Email verification code
- ❌ Email verification link
(Only ONE strategy enabled. Issue reproduces regardless — not a dashboard misconfig.)
Steps
pnpm --filter web build && pnpm --filter web preview(prod-build, no StrictMode dev-time side effects)- Open the preview URL, navigate to
/sign-up - DevTools → Network tab → filter
clerk.→ clear log - Enter a fresh email + valid password, click Continue
- Observe Network panel + inbox
Observed
| Endpoint | Method | Count | Status |
|---|---|---|---|
/v1/client/sign_ups?__clerk_api_version=2025-11-10 |
POST | 1 | 200 |
/v1/client/sign_ups/<id>/prepare_verification?__clerk_api_version=2025-11-10 |
POST | 1 | 200 |
/v1/client/sign_ups/<id> |
PATCH | 0 | — |
| Verification emails received within 60s | — | 2 | first invalidated by second per #887 |
Expected
Exactly 1 verification email per sign-up submission from the prebuilt <SignUp/> widget — without requiring users to drop the widget and write a custom useSignUp() flow.
SDK / Environment
@clerk/react:^6.4.2@clerk/clerk-js(transitive, bundled with@clerk/react@6.4.2)- React:
19.0.x+react-dom@19.0.x - Build tool: Vite 5, prod build (
pnpm build && pnpm preview) - Browser: Chrome (latest stable)
- API version (from request URL):
__clerk_api_version=2025-11-10 - Dashboard strategy: Email verification code enabled; Email verification link disabled
Workaround
The workaround documented in #887 — omit strategy from the create() call, then explicitly call the prepare method — requires rebuilding sign-up as a custom useSignUp() flow. This is not viable for users of the prebuilt <SignUp/> component (the widget owns those calls).
No workaround within the prebuilt widget is known.
References
- #887 —
signIn.prepareFirstFactorsending two emails with different codes (closed 2023-03-03; sign-in side; documents the by-designcreate({strategy})auto-prepare behavior) - clerk/clerk-sdk-flutter#117 —
auth.attemptSignUptriggers two verification code emails (Flutter SDK analog of this exact symptom shape) - #4324 — Receiving Twice Email Verification Codes During Sign-In (possibly related, unresolved as of search; sign-in side,
@clerk/nextjs ^5.7.2)
- Lenguaje dominante
- TypeScript
- Estrellas
- 1.8k
- Forks
- 472
- Merge medio
- 2 d 12 h
- PR fusionados (30 d)
- 222
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de clerk/javascript
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
clerk/javascript#9611 · 1 comentario ·
-
clerk/javascript#9891 · 1 asignado ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 64/100
clerk/javascript#9775 · 1 comentario ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
clerk/javascript#9770 · 3 comentarios ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
clerk/javascript#9667 · 1 comentario ·
Todos los issues de clerk/javascript
Issues similares
-
bug(cli): hapi doctor inline-media prints a fabricated B:\ helper-script path in packaged installs Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Crush Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
catppuccin/catppuccin#3125 ·
-
Add a SECURITY.md Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
ElementsProject/cln-application#167 · 1 comentario · 1 reacción ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Quantco/pnpm-licenses#17 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100