Saltar al contenido principal
Prisma

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.

Error: Unique constraint failed on the fields: (`email`)

¿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.

Prismabase de datosErrorvalidación

¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:

Generador de Prompts

¿Necesitas desarrollo a medida?

Apps web, IA, módulos ERP — cuéntame tu proyecto.