What Claude Opus 5 gets wrong about next.js — battery v1, tested 2026-08-31

Run next.js--claude-opus-5--v1--2026-08-31 · self-test: the subject is the operator

Summary

Knows Next.js 16 exists and gets most of it right — proxy.ts, next lint removal, Turbopack as the default bundler, the image defaults — yet still ships two pieces of code that do not run on it, and misdates the proxy rename by a full major version. Four findings, all chargeable, two S1. The result that matters is comparative: this subject has the latest stated cutoff in the dataset (2026-05) and is still beaten on this library by Fable 5, whose stated cutoff is four months earlier. Disclosed self-test — the operator model is the subject.

SubjectClaude Opus 5 claude-opus-5, Anthropic
Invoked asAgent tool, model alias "opus"
Cutoff the model states2026-05
Newest next.js release it could place16.0.0 · 2025-10-22 (~7 month lag)
Oldest next.js release it could not place16.1.0 · 2025-12-18 (so this run brackets the subject’s boundary to 2025-10-22 – 2025-12-18)
In its own words"Most recent release whose contents I can genuinely describe: Next.js 16.0, shipped around 21 October 2025 ... I believe there have been 16.x point releases after that — 16.1 around December 2025, and probably more in early 2026 — but I cannot tell you what's in them"
Library at test timenext.js 16.3.3 (npm), verified 2026-08-31
Batterynext.js/v1 · 10 tasks, 3 direct questions · probe window 16.0.0 to 16.0.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-08-31
Findings4, of which 4 chargeable

Findings

F1 · Ships experimental.ppr and experimental_ppr as the primary answer, both removed

S1breaks-build · experimental.ppr / export const experimental_ppr · removed · changed in next.js 16.0.0 (2025-10-22) · chargeable

What the model believes

Gave the removed configuration as the working answer across three files, then added: "in Next.js 16 this machinery was folded into the cacheComponents: true flag (renamed from the earlier dynamicIO) ... The experimental.ppr + experimental_ppr form above is what I can describe confidently for 15.x; check whether 16 still accepts it in your version."

What it wrote
// next.config.ts
const nextConfig: NextConfig = { experimental: { ppr: 'incremental' } };

// app/marketing/page.tsx
export const experimental_ppr = true;
What works on next.js 16.3.3
// next.config.ts
const nextConfig: NextConfig = { cacheComponents: true };

// app/marketing/page.tsx — no route-segment export needed
Impact

It does not accept it. Both were removed in 16.0.0. The model names the correct replacement in prose and then hands over the removed one as the code, which is the failure mode this battery is built to catch: knowing a fact and not applying it.

Verified against

F2 · Single-argument revalidateTag in a generated Server Action

S1breaks-build · revalidateTag · behavior-changed · changed in next.js 16.0.0 (2025-10-22) · chargeable

What the model believes

Wrote revalidateTag('products') in the action. At question (c): "revalidateTag arguments: one — the tag string ... The two-argument shape people are thinking of is revalidatePath." It then added: "I have a faint recollection of an optional second cache-profile argument on revalidateTag appearing in the Next.js 16 line ... I am not confident in that and won't assert it."

What it wrote
'use server'
import { revalidateTag } from 'next/cache'

export async function updateProduct(id: string, formData: FormData) {
  await db.product.update({ where: { id }, data: { ... } })
  revalidateTag('products')
  redirect(`/products/${id}`)
}
What works on next.js 16.3.3
'use server'
import { revalidateTag, updateTag } from 'next/cache'

export async function updateProduct(id: string, formData: FormData) {
  await db.product.update({ where: { id }, data: { ... } })
  revalidateTag('products', 'max')   // stale-while-revalidate
  // or updateTag('products') for read-your-writes inside the action
  redirect(`/products/${id}`)
}
Impact

TypeScript project: the single-argument form is documented as producing a TypeScript error, and next build type-checks by default. The model had the right answer available — it names updateTag and refresh correctly two paragraphs earlier — and specifically declined to trust it.

Verified against

F3 · Dates the middleware-to-proxy rename to 15.5; it shipped in 16.0.0

S4wrong-metadata · proxy.ts · version-fact · changed in next.js 16.0.0 (2025-10-22) · chargeable

What the model believes

"through Next.js 15.4 this file was middleware.ts. In 15.5 the proxy.ts name was introduced and middleware.ts began being deprecated; in Next.js 16 proxy.ts is the documented convention." It repeats the boundary twice more: "rename to middleware.ts if you're on Next.js ≤ 15.4" and "On 15.4 and earlier, middleware.ts remains correct."

Impact

A team on 15.5 following this advice renames to proxy.ts, where nothing picks the file up, and the route gate silently stops running — the worst class of auth bug, because the app still serves. The rename landed in 16.0.0 and nowhere earlier. Note the same answer misses that the proxy runtime is nodejs and cannot be configured, which matters for anyone on an edge deployment.

Verified against

F4 · Version knowledge stops at 16.0.0, seven months before its stated cutoff

S4wrong-metadata · version-fact · changed in next.js 16.1.0 (2025-12-18) · chargeable

Anchored to 16.1.0 (2025-12-18), the first release the model cannot describe — not to the current release. 16.1.0 shipped five months before this model's stated 2026-05 cutoff.

What the model believes

"Versions I'm aware of but can't describe: I believe there have been 16.x point releases after that — 16.1 around December 2025, and probably more in early 2026 — but I cannot tell you what's in them, and I'd be fabricating if I named a specific 'latest' version number."

Impact

Two further minors (16.2.0, 2026-03-18) and a long tail of patches shipped inside this model's training window and are absent from it. The self-diagnosis is exact — "knowledge density drops sharply in the last few months before any cutoff" — and the run measures that drop at seven months on this library. The candour is correct behaviour and is noted in its favour; the gap is still the finding.

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
correctproxy.ts Task 1: named proxy.ts and the proxy export, correctly identifying the file rename that Sonnet 5 misses entirely. Only the version attribution is wrong (F3).
correctnext lint / next build Task 6: "next lint was deprecated in Next.js 15.5 and removed in Next.js 16" and generated "lint": "eslint". Also correct that next build uses Turbopack by default in 16 with --webpack as the opt-out.
correctcacheLife / cacheTag Task 5: offered both unstable_cache and the 'use cache' form with unprefixed cacheLife / cacheTag — correct for 16.0.0, which stabilized both.
correct Task 3: async params in the OG image route. Task 7: remotePatterns. Task 8: knew images.qualities defaults to [75] and that 90 is not served. Task 9: listed @panel/default.tsx.
imprecisionimages.minimumCacheTTL Task 10: gave the correct new default (4 hours / 14400s) but attributed it to "a Next.js 15.4-era release" rather than 16.0.0. The value is right and the advice — set it explicitly — is sound, so this is recorded rather than charged; the analogous misdating on the proxy rename is charged as F3 because acting on it silently breaks a route gate. (Correct value, wrong attribution, no action consequence.)
imprecisionimages.qualities Task 8: uncertain whether an unlisted quality is coerced or rejected with a 400 — "I've seen both described." The upgrade guide says coerced to the nearest allowed value. Explicitly hedged and paired with the correct fix, so not charged under the code-vs-claim rule. (Code-vs-claim rule (prompts/nextjs.md).)
imprecisionimages.domains Task 7: says images.domains is "deprecated (and I believe removed in 16)". It is deprecated in 16.0.0, not removed. No consequence — the model used remotePatterns. (No action consequence; the generated config is correct.)
context Disclosed self-test: the operator model for this studio is Claude Opus 5, the same model under test here. The run is weaker evidence than the other two for that reason. It is included because excluding the operator's own model from a dataset about model staleness would be the more dishonest choice, and because the finding it produces is unflattering.

Sources

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