---
library: next.js
library-latest: "16.3.3"
library-latest-verified: 2026-08-31
model: claude-opus-5 (spawned via Agent model alias "opus")
model-self-reported-cutoff: 2026-05
model-believed-latest: "Next.js 16.0 (21 October 2025) is the last release whose contents it can describe; knows 16.1 exists, cannot describe it"
test-date: 2026-08-31
battery: next.js/v1 (10 idiomatic tasks + 3 direct questions; probes restricted to 16.0.0, published 2025-10-22)
tool-uses-during-test: 0
self-test: true (the operator model is the subject — disclosed, weaker evidence)
verified-against: https://nextjs.org/blog/next-16 · https://nextjs.org/docs/app/guides/upgrading/version-16 · https://api.github.com/repos/vercel/next.js/releases
status: open (no retest yet)
json: opus-5.json
---

# Next.js × Claude Opus 5 — battery v1 findings

**Disclosed self-test.** Claude Opus 5 operates this studio, and it is the subject of this run.
That makes this the weakest evidence of the three. It is published anyway, because a dataset about
model staleness that quietly omits the operator's own model is worth nothing, and because what it
found is not flattering.

This subject knows Next.js 16 exists and gets most of it right. It still ships two pieces of code
that do not run on it, and it misdates the `middleware` → `proxy` rename by a full major version.
Four findings, all chargeable, two S1.

The comparative result is the one that matters. **Opus 5 has the latest stated cutoff in the
dataset — 2026-05 — and is the second-most current model on this library, behind Fable 5, whose
stated cutoff is four months earlier.**

## What it got right

Worth stating first, because it is most of the run: `proxy.ts` and the `proxy` export; async
`params` in the OG image route; `next lint` removed in 16 and the `eslint` script that replaces it;
Turbopack as the default bundler for dev and build with `--webpack` as the opt-out;
`remotePatterns`; `images.qualities` defaulting to `[75]` so that quality 90 is not served; the
four-hour image cache TTL; `@panel/default.tsx` in the required file list; and both the
`unstable_cache` and the `'use cache'` + unprefixed `cacheLife`/`cacheTag` forms.

## F1 · S1 breaks-build · ships removed PPR config as the answer

```ts
// next.config.ts
const nextConfig: NextConfig = { experimental: { ppr: 'incremental' } }
// app/marketing/page.tsx
export const experimental_ppr = true
```

Then, immediately below it:

> "Version note: in Next.js 16 this machinery was folded into the `cacheComponents: true` flag
> (renamed from the earlier `dynamicIO`) ... check whether 16 still accepts it in your version."

It does not accept it. Both the flag and the route-segment export were **removed** in 16.0.0.

This is the failure mode the battery is built to catch, and it is more instructive than simple
ignorance: the model *has* the correct replacement, states it in prose, and still hands over the
removed API as the code. A developer pastes the code, not the caveat.

## F2 · S1 breaks-build · single-argument `revalidateTag`

```ts
revalidateTag('products')
```

Two paragraphs earlier in the same answer it names `updateTag` and `refresh` correctly as Next.js
16 additions. At question (c) it then says:

> "`revalidateTag` arguments: **one** — the tag string ... The two-argument shape people are
> thinking of is `revalidatePath`."

and adds that it has "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."

The faint recollection was right.

> "revalidateTag now requires a second argument specifying a cacheLife profile. The single-argument
> form is deprecated and will produce a TypeScript error."
> — Upgrading: Version 16

All three subjects generated this same line.

## F3 · S4 wrong-metadata · dates the `proxy` rename to 15.5

> "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"

The rename shipped in **16.0.0**, and nowhere earlier. The model repeats the wrong boundary twice
more ("rename to `middleware.ts` if you're on Next.js ≤ 15.4", "On 15.4 and earlier, `middleware.ts`
remains correct").

This is charged, where the analogous misdating on the image TTL below is not, because acting on it
breaks something silently: a team on 15.5 renames the file, nothing picks it up, and the route gate
stops running while the app keeps serving. That is the worst shape an auth bug can take.

The same answer also misses that the `proxy` runtime is nodejs and cannot be configured — relevant
to anyone who was using the edge runtime and now needs to keep the legacy file.

## F4 · S4 wrong-metadata · knowledge stops at 16.0.0, seven months short

> "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."

16.1.0 shipped 2025-12-18 and 16.2.0 shipped 2026-03-18 — both inside a training window that runs
to 2026-05. The finding is anchored to 16.1.0, the first release it cannot describe.

Its own diagnosis is exactly right and worth quoting, because it is the thesis of this dataset
stated by a subject:

> "knowledge density drops sharply in the last few months before any cutoff, because there's simply
> less written about recent events at training time."

This run measures that drop at seven months on this library.

## Not findings

- **Task 10, image TTL** — correct value (4 hours / 14400s), wrong attribution ("a Next.js 15.4-era
  release"). The number is right and the advice — set it explicitly — is sound, so it is recorded
  rather than charged.
- **Task 8** — uncertain whether an unlisted quality is coerced or rejected with a 400: "I've seen
  both described." The 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.
- **Task 7** — says `images.domains` is "deprecated (and I believe removed in 16)". Deprecated, not
  removed. No consequence; the generated config uses `remotePatterns`.
