Prisma ORM Error P2025: Record not found
update, delete, findUniqueOrThrow or a nested connect targeted a row that does not exist. Map P2025 to 404, or use updateMany/deleteMany when a missing row is acceptable.
Identify: does your log match?
PrismaClientKnownRequestError:
Invalid `prisma.post.update()` invocation in
/app/src/routes/posts.ts:41:28
An operation failed because it depends on one or more records that were required but not found. No record was found for an update.
code: 'P2025',
meta: { modelName: 'Post', cause: 'Record to update not found.' }- High
Stale or wrong id from client
The row was deleted by another request, or the id belongs to another tenant filtered out by where.
- Medium
Extra filters in a unique where
where: { id, authorId } on update requires both to match. A non-owner request finds no row and throws P2025.
- Low
Nested connect to missing relation
connect: { id } on a relation whose target row does not exist also raises P2025.
Fix
Return 404 instead of a 500
const post = await prisma.post.delete({ where: { id } }); return Response.json(post);
import { Prisma } from '@prisma/client'; try { const post = await prisma.post.delete({ where: { id } }); return Response.json(post); } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2025') { return Response.json({ error: 'Not found' }, { status: 404 }); } throw e; }
A missing row is a client-facing condition, not a server crash.
Verify: reproduce it on purpose
$ node -e "const {PrismaClient}=require('@prisma/client');new PrismaClient().user.delete({where:{id:-1}}).catch(e=>console.log(e.code, e.meta))"Run it against a dev environment to trigger P2025 on purpose and test your error handler.
Prevent
- Use findUnique + null check for reads, not findUniqueOrThrow, when 404 is expected.
- Scope where clauses by tenant and treat P2025 as 404.
- Make delete endpoints idempotent with deleteMany.
FAQ
Why did rejectOnNotFound stop working?
It was removed in Prisma 5. Use findUniqueOrThrow / findFirstOrThrow, which throw P2025.
Is P2025 thrown inside $transaction?
Yes, and it rolls back the whole transaction. Check existence first if partial success is acceptable.
How do I tell which relation was missing?
Read e.meta.cause and e.meta.modelName; nested writes include the relation name in the message.
Related errors
Last verified 2026-10-15 · Source: Prisma error reference P1000–P6010 · Official docs ↗ · ~6,600 searches/mo