Solución: Unique constraint failed en Prisma — campo duplicado
Prisma lanza este error al intentar insertar un valor que ya existe en un campo marcado como único. Cómo capturar el error correctamente y devolver mensajes útiles al usuario.
¿Por qué ocurre?
El campo afectado tiene una restricción UNIQUE en la base de datos y ya existe un registro con ese valor. Es la respuesta correcta del sistema — el problema es que la aplicación no lo gestiona y deja que la excepción llegue al usuario.
Solución paso a paso
Capturar el error de Prisma con PrismaClientKnownRequestError:
import { PrismaClient, Prisma } from '@prisma/client';const prisma = new PrismaClient();
async function crearUsuario(email: string, nombre: string) {
try {
const usuario = await prisma.user.create({
data: { email, nombre },
});
return { ok: true, usuario };
} catch (e) {
// ✅ Detecta el error de unicidad de Prisma
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2002') {
const campo = (e.meta?.target as string[])?.join(', ');
return { ok: false, error: El campo '${campo}' ya está en uso };
}
}
throw e; // relanza errores no esperados
}
}
Códigos de error de Prisma más comunes:
// P2002 → Unique constraint violation (el más común)
// P2003 → Foreign key constraint failed
// P2025 → Record not found (para update/delete)
// P2000 → Value too long for the column type
En un API route de Next.js:
// app/api/registro/route.ts
import { NextResponse } from 'next/server';
import { Prisma } from '@prisma/client';export async function POST(req: Request) {
const { email, password } = await req.json();
try {
const user = await prisma.user.create({
data: { email, password: await hashPassword(password) },
});
return NextResponse.json({ user }, { status: 201 });
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2002') {
return NextResponse.json(
{ error: 'Este email ya está registrado' },
{ status: 409 } // Conflict
);
}
return NextResponse.json({ error: 'Error interno' }, { status: 500 });
}
}
Alternativa — comprobar existencia antes de insertar:
// Busca primero para dar un mensaje más claro (dos queries en vez de una)
const existente = await prisma.user.findUnique({ where: { email } });
if (existente) {
return { error: 'Email ya registrado' };
}
await prisma.user.create({ data: { email, nombre } });
Cómo evitarlo en el futuro
Captura siempre `PrismaClientKnownRequestError` con código P2002 en operaciones de create/upsert sobre campos únicos. Devuelve HTTP 409 (Conflict) cuando el recurso ya existe — no un 500.
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts