| Schema edited, database unchanged | Dev: npx prisma migrate dev; prod/CI: migrate deploy; throwaway prototype only: db push (→ Core Rules 1) |
| "Unknown argument" or a model missing on the client | Client is stale generated code — npx prisma generate (→ Core Rules 2) |
| Renaming a field or table with rows in it | Prisma diffs by name: rename = DROP + ADD. @map to keep the column, or hand-edit the SQL (→ Core Rules 3) |
Existing database, no prisma/migrations folder | db pull to introspect, then baseline the first migration as applied (→ migrations.md) |
"Drift detected" or migrate dev wants to reset prod-like data | Someone changed the DB out of band; diff before you accept anything (→ migrations.md) |
| P3009 — failed migration blocks every deploy | Fix the SQL by hand, then migrate resolve --applied or --rolled-back (→ errors.md) |
| P2002 unique constraint failed | Genuine duplicate or an upsert race — catch the code, retry once (→ errors.md) |
| P2025 record not found on update/delete | Row gone, or an extra where filter did not match — this is the optimistic-locking signal (→ transactions.md) |
| P2024 timed out fetching a new connection | Pool exhausted: long transactions, too many client instances, or a limit below concurrency (→ connections.md) |
| "Too many connections" on Lambda, Vercel or Next.js dev | One client per process behind a globalThis singleton, plus an external pooler (→ connections.md) |
| Query log shows hundreds of queries per request | Relation loads in a loop, not include — measure before rewriting (→ performance.md) |
Relation is undefined at runtime | Prisma never loads relations implicitly; include or select it (→ queries.md) |
| List endpoint gets slower as the table grows | take missing, offset pagination, or count() scanning (→ performance.md) |
| Transaction times out at 5s or deadlocks under load | Shrink the body, raise timeout deliberately, retry P2034 (→ transactions.md) |
| Soft delete, audit trail, tenant scoping, computed fields | Client extensions ($extends), not middleware (→ extensions.md) |
include result does not narrow in TypeScript | GetPayload / validator instead of hand-written interfaces (→ typescript.md) |
Do not know how to serialize a BigInt, or Decimal arrives as an object | Prisma returns BigInt and Decimal, not numbers (→ typescript.md) |
| Query the schema cannot express (CTE, window, DISTINCT ON, upsert-heavy batch) | $queryRaw tagged template, or TypedSQL for typed results (→ raw-sql.md) |
| Deploy fails with "Query engine could not be located" | prisma generate missing from the build, or wrong binaryTargets for the image (→ deployment.md) |
| Tests interfere with each other or need a real database | Per-worker database or schema, rollback-per-test, deterministic seed (→ testing.md) |
| Works on PostgreSQL, breaks on MySQL, SQLite, or MongoDB | Provider capability gap, not a Prisma bug (→ providers.md) |
| Anything else | Turn on query logging and read the SQL Prisma actually sent, then run that SQL by hand: the answer is almost always in the gap between what you expressed and what was emitted (→ performance.md) |