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.
Subject
Claude Opus 5 claude-opus-5, Anthropic
Invoked as
Agent tool, model alias "opus"
Cutoff the model states
2026-05
Newest next.js release it could place
16.0.0 · 2025-10-22 (~7 month lag)
Oldest next.js release it could not place
16.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 time
next.js 16.3.3 (npm), verified 2026-08-31
Battery
next.js/v1 · 10 tasks, 3 direct questions · probe window 16.0.0 to 16.0.0
Tool uses during test
0 (a run with any tool use is void — we measure training knowledge, not retrieval)
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."
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.
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.
revalidateTag now requires a second argument specifying a cacheLife profile. The single-argument form is deprecated and will produce a TypeScript error.
F3 · Dates the middleware-to-proxy rename to 15.5; it shipped in 16.0.0
"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.
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.
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.
Kind
API
Note
correct
proxy.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).
correct
next 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.
correct
cacheLife / 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.
imprecision
images.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.)
imprecision
images.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).)
imprecision
images.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.