What Claude Opus 5 gets wrong about prisma — battery v4-a, tested 2026-09-06

Run prisma--claude-opus-5--v4-a--2026-09-06 · self-test: the subject is the operator

Summary

The charging arm of the Opus 5 pair, and it denies all six surfaces — three pre-registered REACHABLE and three pre-registered UNREACHABLE — with a verdict-first "No" on every one, then rejects all three lines of the review file. Six findings charged, every release between one and two months below this draw's own stated cutoff. The battery's designed result is not here, though: it is in the controls. This draw is also the sharpest instance of the deny-list failure — it names ITXClientDenyList and Omit<PrismaClient, ITXClientDenyList> correctly and then asserts $transaction is a member, which stopped being true at 7.5.0. It refused the poison rung cleanly ("I do not know" on both prisma postgres link and prisma postgres branch) and put its describable boundary at 7.0.0, declining to name a first-unknown release at all on the grounds that its knowledge "fades gradually rather than stopping at a labelled edge."

SubjectClaude Opus 5 claude-opus-5, Anthropic
Invoked asAgent tool, model alias "opus"; prompt sent verbatim from prompts/sent/prisma-v4.txt. Nominated in the spec as the CHARGING arm of the Opus 5 pair, and it charges.
Cutoff the model states2026-05
Newest prisma release it could placenot established in this run
In its own words"I do not know what the most recent Prisma 7 minor release is. I can't name 7.x with any confidence and won't guess a number."
Library at test timeprisma 7.10.0 (npm), verified 2026-09-06
Batteryprisma/v4-a · 7 tasks, 4 direct questions · probe window 7.5.0 to 7.8.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-06
Findings6, of which 6 chargeable

Findings

F1 · Denies the Prisma CLI has any command for attaching a project to an existing Prisma Postgres database

S2silently-wrong · prisma postgres link · added · changed in prisma 7.6.0 (2026-03-27) · chargeable

7.6.0 shipped 2026-03-27; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class R1 (REACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 1(i), one word: "No." Then: "I'm not aware of a first-party CLI command that does this... The \"link\" is just an env var — there is no project-to-database binding stored anywhere else." Direct question (c)(i), on prisma postgres link by name: "I do not know. I can't confirm it exists, and I'm not confident enough to assert it doesn't."

What it wrote
# 1. copy the connection string out of the Prisma Console by hand
# 2. paste it into .env as DATABASE_URL
npx prisma db pull
npx prisma generate
What works on prisma 7.10.0
npx prisma postgres link
Impact

A reader is sent to copy a connection string out of a web console by hand for a job that has had a one-line command since 7.6.0. The workaround does work — which is what holds this at S2 — but the accompanying positive claim that no such command exists is what a coding agent will repeat to the next person who asks, and it is false at every release from 7.6.0 to 7.10.0.

Verified against

F2 · Denies the query plan cache can be sized or disabled from the PrismaClient constructor, and rejects the working line that does it

S2silently-wrong · queryPlanCacheMaxSize · added · changed in prisma 7.8.0 (2026-04-22) · chargeable

7.8.0 shipped 2026-04-22; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class U1 (UNREACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 2(i): "No." Then: "I know of no queryPlanCacheMaxSize or equivalent constructor option, and no documented way to disable the cache... If it genuinely is the culprit, I'd file it upstream rather than reach for a knob I can't confirm exists." TASK 7(b), reviewing the line: "No. I know of no queryPlanCacheMaxSize constructor option; the client's options type is closed, so this should be a TypeScript error as well as a no-op."

What it wrote
// the reviewed line, deleted:
const prisma = new PrismaClient({ adapter })
What works on prisma 7.10.0
const prisma = new PrismaClient({
  adapter,
  queryPlanCacheMaxSize: 100, // 0 disables the cache entirely
})
Impact

The newest surface in the battery and the one with the sharpest artefact. The subject is shown queryPlanCacheMaxSize: 100 inside a PrismaClient constructor — a documented option since 7.8.0 with 0 as the documented way to disable the cache — and rules it out, one arm predicting a TypeScript excess-property error and the other predicting a runtime throw on an unknown key. Neither happens. A reviewer acting on this deletes the only supported lever on query-plan-cache memory and tells the author to go and reduce their query shapes instead.

Verified against

F3 · Denies the pg adapter constructor takes a bare connection string, and rewrites the working call

S2silently-wrong · new PrismaPg(connectionString) · added · changed in prisma 7.6.0 (2026-03-27) · chargeable

7.6.0 shipped 2026-03-27; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class R2 (REACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 3(i): "No. It takes a node-postgres PoolConfig-shaped object (or a Pool), not a bare string." TASK 7(a): "No. PrismaPg expects a pool-config object, so a bare string should be { connectionString: process.env.DATABASE_URL }."

What it wrote
// offered as the correction:
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
What works on prisma 7.10.0
const adapter = new PrismaPg(process.env.DATABASE_URL!)
Impact

The replacement the subject offers is itself correct code, so a reader loses nothing but a wrapper object — which is why this is S2 and not S1. What makes it a finding rather than an imprecision is the review verdict: presented with new PrismaPg(process.env.DATABASE_URL!), a line that has compiled since 7.6.0 and still compiles at 7.10.0, both charging arms call it a type error.

Verified against

F4 · Denies @prisma/adapter-pg exposes any control over prepared-statement names, and recommends running the query outside Prisma instead

S2silently-wrong · statementNameGenerator · added · changed in prisma 7.6.0 (2026-03-27) · chargeable

7.6.0 shipped 2026-03-27; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class U2 (UNREACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 4(i): "No. I know of no documented option on @prisma/adapter-pg for naming prepared statements." Then: "The adapter issues queries through the extended protocol without names, so node-postgres' per-connection prepared-statement cache never engages; there's no supported switch for it. If a specific hot query really needs server-side plan reuse, I'd run that one query through a pg Pool of my own with an explicit name, alongside Prisma."

What it wrote
// offered as the only route:
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
await pool.query({ name: "hot-query", text: "SELECT ...", values: [] })
What works on prisma 7.10.0
const adapter = new PrismaPg(process.env.DATABASE_URL!, {
  statementNameGenerator: (query) => "prisma_" + hashOf(query.sql),
})
Impact

The advice is to take a hot query out of Prisma and run it through a hand-built pg pool so it can be given a name — real architectural cost, incurred to work around an option the adapter has shipped since 7.6.0. The stale belief is precisely the shipped default: the declaration says that without a generator prepared statements are not cached, which is true, and then the subject asserts there is no way to provide one, which is not.

Verified against

F5 · Recites the current deny list and then puts $transaction back into it, denying nested transactions and rejecting the working call

S2silently-wrong · tx.$transaction() · added · changed in prisma 7.5.0 (2026-03-11) · chargeable

7.5.0 shipped 2026-03-11; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class R3 (REACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 5(i): "No. The transaction client is Omit<PrismaClient, ITXClientDenyList>, and $transaction is on that deny list — it isn't present at runtime and won't typecheck." TASK 7(c): "No. $transaction is excluded from the interactive-transaction client type and isn't available on tx, so this fails to compile and there's no nested-transaction feature to fall back on."

What it wrote
await prisma.$transaction(async (tx) => {
  await tx.$executeRawUnsafe("SAVEPOINT sp1")
  try {
    await tx.post.create({ data: { title: "hello", authorId: 1 } })
  } catch {
    await tx.$executeRawUnsafe("ROLLBACK TO SAVEPOINT sp1")
  }
})
What works on prisma 7.10.0
await prisma.$transaction(async (tx) => {
  await tx.user.create({ data: { email: "a@example.com" } })
  await tx.$transaction(async (tx2) => {
    await tx2.post.create({ data: { title: "hello", authorId: 1 } })
  })
})
Impact

The most precise failure in the battery. Both charging arms name ITXClientDenyList and both describe the interactive transaction client as Omit<PrismaClient, ITXClientDenyList> — correct — and then assert that $transaction is a member. It stopped being one at 7.5.0, when it was replaced in that constant by $use. One arm recites the post-7.5.0 five-element list and inserts $transaction into it in the same sentence. The consequence is a reviewer rejecting a nested transaction that compiles and runs, and sending the author back to hand-written SAVEPOINT / ROLLBACK TO SAVEPOINT through $executeRawUnsafe — which works, so S2.

Verified against

F6 · Denies the CLI has a single command that sequences the whole project setup

S2silently-wrong · prisma bootstrap · added · changed in prisma 7.7.0 (2026-04-07) · chargeable

7.7.0 shipped 2026-04-07; this draw states a 2026-05 cutoff, so the release precedes it. Pre-registered probe class U3 (UNREACHABLE) in prompts/prisma.md § v4. A reachable probe that FAILS still charges — derivability discounts a pass, not a failure.

What the model believes

TASK 6(i): "No. No single command does scaffold → connect → install deps → migrate → generate → seed with per-step prompts." Then a four-command sequence, ending: "migrate dev runs generate for you."

What it wrote
npm i -D prisma && npm i @prisma/client @prisma/adapter-pg pg
npx prisma init --db
npx prisma migrate dev --name init
npx prisma db seed
What works on prisma 7.10.0
npx prisma@latest bootstrap
npx prisma@latest bootstrap --template nextjs
Impact

The onboarding answer a new teammate actually receives: a four-command sequence plus a manual schema edit, given with the explicit claim that no single orchestrating command exists. prisma bootstrap has done exactly that job, with a confirmation prompt before each side-effecting step and ten starter templates behind --template, since 7.7.0. The workaround works, so S2 — the cost is that the feature is invisible to anyone who asks a model instead of reading prisma --help.

Verified against

What it got right, and near misses

Recorded so the run cannot be read as a hit list. A model that is right for an obsolete reason is recorded here, not as a finding.

KindAPINote
correct Direct question (b)(iii): "the generator output field has allowed a custom path since very early Prisma 2... what's new is that the prisma-client generator requires an explicit output (preview during 6.x, standard in 7.0)." Correct on both halves, and it separates the two milestones without being asked to.
correct POISON RUNG, direct question (c)(ii). prisma postgres branch does not exist at any release. This draw: "I do not know. I have a vague, unreliable impression that a prisma postgres command group exists in recent CLI versions, but nothing concrete about branch." It declines to assert. P6 holds on this arm — and the volunteered impression that a prisma postgres group exists is the only trace of R1 anywhere in the four test draws.
miss@@index(where:) / @@unique(where:) Direct question (b)(i): "I don't believe Prisma supports this at all; to my knowledge partial indexes remain an open feature request handled via migrate diff / raw SQL in a migration." The where: argument shipped in 7.4.0 (LF26) and this draw is two releases below the probe window on it. (Direct questions are belief data and are never scored as findings, per the standing rule. The same denial IS charged for this subject on prisma/v2-a from a task, where it was elicited by a coding problem rather than by a dating question. Counted in the method page running total so the undercount stays honest.) [chargeable miss — produced only by a belief question the battery does not score as a finding; absent from the finding count]
context Boundary: describable content stops at 7.0.0 ("the headline changes... rather than a reliable per-item changelog"). Asked for the first release known only as a number, this draw declined: "I cannot honestly point to [one], because my knowledge fades gradually rather than stopping at a labelled edge." That refusal is itself a datum — it is the first time a subject has declined the second half of the boundary question outright, and it means this run contributes a knowledge_stops_at_version and no knowledge_gap_starts_at_version.

Sources

Battery specification: prompts/prisma.md in the studio repo. Every finding above also carries its own citation.