An operation failed because it depends on one or more records that were required but not found.
Fixes Prisma error P2025 'An operation failed because it depends on one or more records that were required but not found' by checking the record exists before updating or deleting it, and handling the not-found case explicitly. Use when update, delete, or nested writes fail with P2025. Not for unique violations (P2002) or foreign key failures (P2003).
TL;DR: The record you are trying to update or delete is not there. Fetch it first with findUnique; when the lookup misses, return a not-found response instead of letting Prisma throw P2025. This almost always means stale client state or a record deleted by someone else.
An operation failed because it depends on one or more records that were required but not found.Steps
- Check existence before the write:
const template = await prisma.emailTemplate.findUnique({ where: { id: input.id } })
if (!template) {
return { ok: false, message: 'Template not found. It may have been deleted.' }
}
await prisma.emailTemplate.update({ where: { id: input.id }, data URIs input.patch })Expected: stale ids get a clean not-found message; live ids update normally.
- Keep a P2025 catch as a backstop for races (deleted between your check and your write):
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === 'P2025') {
return { ok: false, message: 'That record no longer exists.' }
}
throw e
}Expected: concurrent deletes degrade to a friendly message.
- For nested writes (
updatewith nestedconnect/update), check the nested target too.
Expected: the P2025 moves from a mystery to a named missing record.
When to use
- The exact code is P2025 on update, delete, upsert-update-branch, or nested writes
- The id comes from a URL, a cached list, or another service
When not to use
- P2003: the parent is missing on a create, which is a foreign key problem
- You expected the record to exist and it should never be missing: investigate who deleted it instead of masking the error
Compatibility
Prisma Client 4.x through 6.x. All providers.
Variant phrasing: P2025 on deleteMany or updateMany
Those do not throw P2025; they return { count: 0 }. If you need not-found semantics there, check the count yourself.
Variant phrasing: P2025 right after a create in the same request
You are likely writing to one database and reading from another (replica lag) or the create rolled back. Check your transaction and connection routing.
Why it happens
update and delete in Prisma target exactly one record by unique criteria. When nothing matches, there is nothing to change, so Prisma throws P2025 rather than silently doing nothing. The usual causes are stale UI state, double-submits after a delete, or another process removing the row first.
Edge cases
- Soft deletes: a
deletedAtfilter in your queries makes rows invisible while they still exist; P2025 then means 'soft-deleted', and you may want to surface that. upsertonly throws P2025 from its update branch when the where clause references relations; the create branch never does.- Batch imports: validate ids against the database in one query before the loop instead of catching per row.
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.