Prisma P2002 "Unique constraint failed on the fields": the race two users win at the same moment, and the retry that actually works
Problem
A signup endpoint that intermittently throws P2002 — almost always when a user double-clicks "Sign up" or a frontend retry fires in parallel with the first request:
PrismaClientKnownRequestError:
Invalid `prisma.user.create()` invocation:
Unique constraint failed on the constraint: `users_email_key`
code: P2002
meta: { target: ['users_email_key'] }The application's own pre-check (findUnique then create) runs on every request. The error happens anyway.
Root cause
P2002 is Postgres telling you the truth: two transactions tried to insert the same unique value, and the database's constraint — not your application check — is the arbiter. The check-then-insert pattern has a TOCTOU window no amount of application locking fixes across processes:
// both parallel requests can pass this line before either inserts
const existing = await prisma.user.findUnique({ where: { email } });
if (!existing) {
await prisma.user.create({ data: { email, name } }); // second one wins P2002
}The bug class also appears in the innocent form: a username field added with @unique after the fact, where legacy code paths that never knew about the constraint now collide. The database constraint is doing its job; the fix is to treat P2002 as a normal, expected outcome of concurrent work — not as a 500.
import { Prisma } from '@prisma/client';
export async function registerUser(input) {
… 19 more lines in the fix🔒 the fix — including 2 code blocks — is members-only. $1/mo unlocks everything.