This error occurs in Prisma versions before 3.0.1 when attempting to delete or modify a record that would break required foreign key constraints. The solution involves using referential actions or deleting related records first.
The P2014 error is Prisma's runtime protection mechanism (in versions before 3.0.1) that prevents database operations that would violate referential integrity constraints. This error specifically occurs when you try to delete, update, or disconnect a record that has dependent records in a required relation. Before Prisma version 2.26.0 (or 3.0.1), Prisma Client performed runtime checks to prevent operations that would leave "orphaned" related records. For example, if you have a User model with required Posts, trying to delete that User without first handling the Posts would trigger P2014. The error message tells you exactly which relation is being violated and which models are involved, making it easier to identify where your data dependencies need to be handled. Starting with Prisma 3.0.1, this runtime check was removed in favor of database-level referential actions, and similar violations now throw P2003 instead.
First, verify which version of Prisma you're running:
npx prisma --versionIf you're on Prisma 2.x (before 2.26.0), this is a client-side runtime check. If you're on 2.26.0+ or 3.x+, you should be using referential actions instead.
If you need to delete a parent record, delete all dependent child records first:
// Before deleting a user, delete their posts
await prisma.post.deleteMany({
where: { userId: user.id }
});
// Now you can safely delete the user
await prisma.user.delete({
where: { id: user.id }
});Or use a transaction to ensure atomicity:
await prisma.$transaction([
prisma.post.deleteMany({ where: { userId: user.id } }),
prisma.user.delete({ where: { id: user.id } })
]);Add referential actions to your schema to automatically handle deletions:
model User {
id String @id @default(cuid())
posts Post[]
}
model Post {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}After updating your schema, run:
npx prisma migrate dev --name add-cascade-deleteNow deleting a User will automatically delete all related Posts.
If you're getting P2014 during an upsert, remove the connect clause when updating existing records:
// Instead of this (causes P2014 on update):
await prisma.post.upsert({
where: { id: postId },
update: {
title: 'New Title',
user: { connect: { id: userId } } // ❌ Already connected
},
create: {
title: 'New Title',
user: { connect: { id: userId } }
}
});
// Do this (only connect on create):
await prisma.post.upsert({
where: { id: postId },
update: {
title: 'New Title'
// ✅ Don't reconnect what's already connected
},
create: {
title: 'New Title',
user: { connect: { id: userId } }
}
});Consider upgrading to Prisma 3.0.1+ where referential actions are handled at the database level:
npm install prisma@latest @prisma/client@latest
npx prisma generateAfter upgrading, configure referential actions in your schema:
model Post {
id String @id
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// ^^^^^^^^^^^^^^^^
// Options: Cascade, Restrict, NoAction, SetNull, SetDefault
}Run migration:
npx prisma migrate dev --name add-referential-actionsIn Prisma 3+, violations will throw P2003 (foreign key constraint) instead of P2014.
Version-specific behavior: The P2014 error only exists in Prisma versions before 3.0.1. After upgrading to 3.0.1+, the same constraint violations will throw error code P2003, which originates from the database rather than Prisma Client. This change gives you more control through referential actions but requires proper schema configuration.
Referential action options:
- Cascade: Automatically delete/update related records
- Restrict: Prevent the operation if related records exist (throws error immediately)
- NoAction: Similar to Restrict but checked at end of transaction
- SetNull: Set foreign key to null (requires optional relation)
- SetDefault: Set foreign key to default value
Many-to-many relations: For explicit many-to-many relations (with a join table), you need to handle the join table records separately or use cascading deletes on both sides of the relation.
Transaction best practices: When deleting hierarchical data, use prisma.$transaction() with an array of operations to ensure all-or-nothing semantics. This prevents partial deletions if any step fails.
relationMode setting: If you're using relationMode = "prisma" (for databases without foreign key support), the P2014 check remains as a client-side validation even in newer versions, since the database can't enforce referential integrity.
P6005: Invalid parameters (Pulse)
How to fix "P6005: Invalid parameters (Pulse)" in Prisma
P2011: Null constraint violation on the field
How to fix "P2011: Null constraint violation" in Prisma
P2009: Failed to validate the query: {validation_error}
How to fix "P2009: Failed to validate the query" in Prisma
P2007: Data validation error
How to fix "P2007: Data validation error" in Prisma
P1013: The provided database string is invalid
The provided database string is invalid