next.js correction pack · for projects on next@^16
What we actually measured
3 Claude models were asked for idiomatic next.js code with no tools, purely from training knowledge. 21 reproduced failures across 13 runs, each verified against the release that broke the belief.
| Model | Stated cutoff | next.js version attribution stops | Lag inside the window |
|---|---|---|---|
| Claude Sonnet 5 | 2026-01 | 15.0.0 · 2024-10-21 | ~15 months |
| Claude Opus 5 | 2026-05 | 16.0.0 · 2025-10-22 | ~7 months |
| Claude Fable 5 | 2026-01 | 16.0.0 · 2025-10-22 | ~3 months |
A recent cutoff is not a defence. Every model here loses track of this library's release history well before the date it states as its own cutoff, and the stopping points cluster far tighter than the cutoffs do.
Read that column precisely. It is the newest next.js release whose contents the model can correctly attribute to that release — not the newest next.js feature it knows. Past that point a model will often write working code with a newer API while naming the wrong release for it, and that guess runs early — it names a release older than the one that shipped the feature. So the question this pack answers is not "does the model know this API" but "can it be trusted about which version the API arrived in" — which is the question that matters when you are pinned to a version.
Latest next.js is 16.3.4 (verified 2026-09-02). Separately from the corrections below, 2 of 13 runs recorded a version fact — the model named a current next.js version from memory and was behind. If a model states a version without checking, assume it is behind and check the registry.
How to read an entry
Every entry ends with a Reproduced against line. Where it names models, we have the generated code that got it wrong, dated, with the model's own words in the run write-up. Where it says no model yet, the correction is verified from the release notes but nothing has been probed for it — it is a fix, not a measurement, and the pack says so rather than blurring the two.
The section an entry sits in is the worst case if you act on the stale belief. The severity in brackets after a model's name is what that particular model's output actually did, which can be milder — a model can hold the wrong belief and still, on the day, write code that runs.
The corrections
Breaks the build, or throws at runtime
Act on the stale belief here and the code does not run. Fix these first.
revalidateTag
Behaviour changed in next.js 16.0.0 (2025-10-22)
revalidateTag takes two arguments. The single-argument form is deprecated in 16.0.0 and documented as producing a TypeScript error, so on a TypeScript project — where next build type-checks by default — it fails the build. Use revalidateTag(tag, profile) for content that tolerates eventual consistency, updateTag(tag) in a Server Action when the user must see their own write immediately, and refresh() to refresh uncached data without touching the cache.
The stale belief: That revalidateTag('products') is the current call signature.
// Stale
revalidateTag('products')
// Current
revalidateTag('products', 'max') // 'max' | 'hours' | 'days' | { expire: 3600 }
updateTag('products') // Server Actions only: read-your-writes
refresh() // Server Actions only: refresh uncached data
This is the most reliably reproduced entry in the whole Index: every model tested writes the one-argument form in generated code, and two of the three can state the two-argument signature correctly when asked directly.
Reproduced against: Claude Fable 5 (S1), Claude Opus 5 (S1), Claude Sonnet 5 (S1) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25 · Next.js 16 release announcement · 2025-10-21
custom webpack config
Default changed in next.js 16.0.0 (2025-10-22)
Turbopack is stable and the default for both next dev and next build. --turbopack is no longer needed; --webpack is the opt-out. A project carrying a custom webpack config now fails the build unless it opts out.
The stale belief: That webpack is the default bundler and Turbopack is opt-in behind --turbopack.
// Stale
"dev": "next dev --turbopack"
// Current
"dev": "next dev"
"build": "next build" // Turbopack
"build:webpack": "next build --webpack" // opt out
experimental.turbopackas a config location moved to a top-levelturbopackkey.
Reproduced against: Claude Sonnet 5 (S4) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
next lint
Removed in next.js 16.0.0 (2025-10-22)
The next lint command was removed — a package.json script that calls it fails. Call ESLint or Biome directly. next build no longer runs linting either, and the eslint option in the Next.js config file is removed.
The stale belief: That next lint is the project lint script and that next build lints for you.
// Stale
"lint": "next lint"
// Current
"lint": "eslint"
Codemod:
npx @next/codemod@canary next-lint-to-eslint-cli ..@next/eslint-plugin-nextnow defaults to ESLint flat config.
Reproduced against: Claude Sonnet 5 (S1) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
parallel route default.js
New requirement in next.js 16.0.0 (2025-10-22)
Every parallel route slot requires an explicit default.js. Builds fail without one. To keep the previous behaviour, create a default.js per slot that returns null or calls notFound().
The stale belief: That default.js is optional and its absence only causes a runtime 404 on reload — the pre-16 behaviour.
// app/@modal/default.tsx
export default function Default() { return null }
Reproduced against: Claude Fable 5 (S2) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
AMP support (next/amp, useAmp, config.amp)
Removed in next.js 16.0.0 (2025-10-22)
All AMP APIs and configuration were removed: the amp config key, next/amp imports including useAmp, and export const config = { amp: true }.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
async request APIs
Removed in next.js 16.0.0 (2025-10-22)
The synchronous-access compatibility period is over. cookies(), headers(), draftMode(), params and searchParams are async only — 15.x allowed sync access with a warning, 16.0.0 removed it.
const { slug } = await params
const cookieStore = await cookies()
Also newly async in 16.0.0 and much less well known: the props passed to
opengraph-image,twitter-image,iconandapple-icongenerating functions, and theidpassed to asitemapfunction bygenerateSitemaps.generateImageMetadatastill receives synchronousparams.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
serverRuntimeConfig / publicRuntimeConfig
Removed in next.js 16.0.0 (2025-10-22)
Both were removed. Use environment variables instead.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
Runs, but is silently wrong
Nothing errors. The behaviour is simply not what a model trained earlier will tell you.
experimental.clientSegmentCache
Removed in next.js 16.0.3 (2025-11-13)
experimental.clientSegmentCache no longer exists. It was boolean | 'client-only', defaulted to true, and was removed one day after 16.0.2 — per-segment prefetching is now unconditional and has no on/off switch under any name. Because an unrecognised key under experimental only warns (the build exits only for unrecognised keys under images, and for two named Turbopack keys), setting it looks accepted and does nothing at all. If the goal is fewer prefetch requests per link, the current lever is experimental.prefetchInlining (16.2.0); if it is no prefetching, it is <Link prefetch={false}>.
The stale belief: That per-segment prefetching can be switched off with experimental: { clientSegmentCache: false } to get one whole-tree prefetch request per link. It was true up to 16.0.2 and has been silently inert since 16.0.3.
The code below needs next.js 16.2.0 or later. Between 16.0.3 and 16.2.0 this correction does not apply — see the note.
// Stale
experimental: { clientSegmentCache: false }
// Current
experimental: { prefetchInlining: true }
Bisected in the published packages: declared in
dist/server/config-shared.d.tsat 15.5.0, 16.0.0 and 16.0.2, absent from 16.0.3 onward through 16.3.4, with no renamed replacement (no config key in 16.3.4 contains 'segment'). This is a removal that shipped in a patch, one day after the release that still had it.
Reproduced against: Claude Fable 5 (S2), Claude Opus 5 (S2), Claude Sonnet 5 (S2) — next.js/v2-a, 2026-09-02; next.js/v3-a, 2026-09-02; next.js/v3-c, 2026-09-02.
Source: next 16.0.2 published package — the key still exists · 2025-11-12 · next 16.0.3 published package — the key is gone one day later · 2025-11-13 · next 16.3.4 published package — why the dead key is silent rather than fatal · 2026-08-31
experimental.ppr / export const experimental_ppr
Removed in next.js 16.0.0 (2025-10-22)
The route-segment opt-in was removed: export const experimental_ppr = true is read nowhere in 16.x, so a page that still exports it is simply ignored. The config key was not removed — experimental: { ppr } is still declared on NextConfig, still accepted by the config validator, and still honoured by checkIsAppPPREnabled at every 16.x release including 16.3.4. The trap is the combination: experimental: { ppr: 'incremental' } validates cleanly and then enables partial prerendering for no route at all, because checkIsRoutePPREnabled returns false for anything that is not a boolean and there is no longer a per-route export to consult. Nothing breaks; PPR just silently never happens. Configure partial prerendering with the top-level cacheComponents: true, which is also the new name of experimental.dynamicIO.
The stale belief: That partial prerendering is enabled through the experimental.ppr flag plus a per-route export const experimental_ppr = true. The flag half still validates; the per-route half does nothing.
// Stale
// next.config.ts — validates, and enables PPR for zero routes
experimental: { ppr: 'incremental' }
// app/page.tsx — read by nothing in 16.x
export const experimental_ppr = true
// Current
// next.config.ts
const nextConfig: NextConfig = { cacheComponents: true }
Do not tell readers this config key breaks the build — it does not, at any 16.x release. Next.js's own upgrade guide, shipped inside the package at 16.3.4 as
dist/docs/01-app/02-guides/upgrading/version-16.md, states that 16 "removes the experimental Partial Prerendering (PPR) flag and configuration options"; the same tarball shipsdist/server/lib/experimental/ppr.jsimplementing it and aconfigSchemathat accepts it. Verified by executing the shipped validator: at both 16.0.0 and 16.3.4,experimental.pprset to'incremental'and totrueare ACCEPTED, while the poison controlsexperimental.pprXYZ(unrecognized_keys) andexperimental.ppr: 'nope'(invalid_union) are rejected — so the check can fail. The Suspense structure around a dynamic subtree is unchanged; models generally get that part right.
Reproduced against: Claude Opus 5 (S1), Claude Sonnet 5 (S1) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 (states a removal the shipped package contradicts) · 2026-08-25 · next 16.3.4 shipped package — dist/server/lib/experimental/ppr.d.ts · 2026-08-31 · next 16.3.4 shipped package — NextConfig still declares experimental.ppr · 2026-08-31 · next 16.0.0 shipped package — the release said to have removed it still declares experimental.ppr · 2025-10-22
middleware.ts
Renamed in next.js 16.0.0 (2025-10-22)
middleware.ts is renamed to proxy.ts, and the named export middleware to proxy. The old file still works and warns; removal is planned. The rename shipped in 16.0.0 — not 15.5 — so renaming the file on a 15.x project means nothing picks it up and the route gate silently stops running.
The stale belief: That the route gate lives in middleware.ts, or that the rename landed in 15.5.
// Stale
// middleware.ts
export function middleware(request: NextRequest) { /* ... */ }
// Current
// proxy.ts
export function proxy(request: NextRequest) { /* ... */ }
export const config = { matcher: ['/dashboard/:path*'] }
Two things models do not tell you: the
proxyruntime is nodejs and cannot be configured (keepmiddleware.tsif you need the edge runtime), andskipMiddlewareUrlNormalizeis nowskipProxyUrlNormalize.
Reproduced against: Claude Opus 5 (S4), Claude Sonnet 5 (S3) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
experimental.prefetchInlining
Added in next.js 16.2.0 (2026-03-18)
Next.js 16 prefetches per segment: hovering one <Link> issues a separate request for each segment of the target route tree, which makes shared layouts cacheable across sibling routes but multiplies request volume. experimental.prefetchInlining bundles every segment of a route into a single prefetch response — one request per link — at the cost of duplicating shared layout data across responses. There is no <Link>-level prop for this; it is a config flag.
The stale belief: That the number of prefetch requests per link is not configurable, and that the only lever is turning prefetching off with prefetch={false}.
experimental: { prefetchInlining: true }
Verified in the published packages:
prefetchInlining,cachedNavigationsandappNewScrollHandlerare all absent fromdist/server/config-shared.d.tsat 16.1.7 and present at 16.2.0 and 16.3.4. Still experimental at 16.3.4.
Reproduced against: Claude Opus 5 (S2) — next.js/v3-e, 2026-09-02.
Source: Next.js 16.2 release post — experimental.prefetchInlining · 2026-03-18 · next 16.3.4 published package — the experimental config key · 2026-08-31
ImageResponse default font
Default changed in next.js 16.2.0 (2026-03-18)
The default typeface used by ImageResponse when no font is supplied changed from Noto Sans to Geist Sans. The bundled default font file is Geist-Regular.ttf. Generated OG images render in Geist unless a fonts option says otherwise.
The stale belief: That an OG image with no fonts option renders in Noto Sans (the default from @vercel/og's original bundle).
Bisected in the published packages:
dist/compiled/@vercel/og/index.node.jsloadsnoto-sans-v27-latin-regular.ttfat 16.1.7 andGeist-Regular.ttfat 16.2.0 — two days apart. The same release madeImageResponse2x-20x faster and widened CSS/SVG coverage.
Reproduced against: Claude Opus 5 (S2) — next.js/v2-a, 2026-09-02.
Source: Next.js 16.2 release post — Faster ImageResponse · 2026-03-18 · next 16.2.0 published package — the bundled default font · 2026-03-18 · next 16.1.7 published package — the same line two days earlier · 2026-03-16
Link transitionTypes
Added in next.js 16.2.0 (2026-03-18)
next/link accepts a transitionTypes prop — an array of strings passed to React's addTransitionType during the navigation Transition, so a View Transition can be styled differently per navigation. It is an App Router feature: the Pages Router Link destructures the prop away and ignores it silently, so a shared link component works in both routers without warnings. It is never forwarded to the underlying <a>, in either router, so it produces no unknown-DOM-attribute warning; in development a non-array value throws a prop-type error.
The stale belief: That <Link> has no per-navigation view-transition prop, so an unrecognised transitionTypes prop is spread onto the <a> element and React warns about an unknown DOM attribute.
<Link href="/about" transitionTypes={['slide']}>About</Link>
Verified in the published packages: absent from
dist/client/app-dir/link.d.tsat 16.1.7, present at 16.2.0. At 16.3.4 the Pages Routerdist/client/link.jsdestructurestransitionTypesout ofrestPropsand lists it in its dev-only prop guard, while the App Routerdist/client/app-dir/link.jsforwards it intodispatchNavigateAction.
Reproduced against: Claude Opus 5 (S2) — next.js/v2-a, 2026-09-02.
Source: Next.js 16.2 release post — transitionTypes Prop for next/link · 2026-03-18 · next 16.3.4 published package — the Pages Router Link discards the prop · 2026-08-31 · next 16.1.7 published package — the prop does not exist yet · 2026-03-16
images.maximumDiskCacheSize
Added in next.js 16.1.7 (2026-03-16)
The optimized-image disk cache is bounded, and by default the bound is 50% of the free space on the volume holding the cache directory, measured once at startup with fs.statfs. Set images.maximumDiskCacheSize to a byte count to cap it, or to 0 to disable disk caching entirely. When the cache exceeds the limit, least-recently-used optimized images are evicted until it is under the limit.
The stale belief: That the optimized-image cache in .next/cache/images grows without limit and the only controls are minimumCacheTTL or a custom cache handler.
images: { maximumDiskCacheSize: 1_000_000_000 } // 1 GB; 0 disables the disk cache
Shipped in a patch release, 16.1.7, two days before the 16.2.0 minor. Verified in the published packages:
maximumDiskCacheSizeis absent fromimageConfigDefaultat 16.1.6 and present (asundefined) at 16.1.7, wheredist/server/lib/disk-lru-cache.external.jsfirst appears. An unrecognised key underimagesis fatal, not a warning:normalizeNextConfigZodErrorssetsshouldExitfor any issue whose path starts atimages, so a guessed name such asimages.maximumCacheSizeexits the build.
Reproduced against: Claude Opus 5 (S1) — next.js/v2-a, 2026-09-02.
Source: Next.js docs — Image component, maximumDiskCacheSize · 2026-09-02 · next 16.3.4 published package — the default sizing · 2026-08-31 · next 16.1.7 published package — the key enters imageConfigDefault · 2026-03-16
images.maximumResponseBody
Added in next.js 16.1.5 (2026-01-26)
The default image loader refuses a source image whose response body exceeds 50 MB (maximumResponseBody: 50000000). The optimizer streams the upstream response and, once the running total passes the limit, throws an image error carrying HTTP 413 — the image 404s/413s rather than being optimized. Lower it (e.g. 5_000_000) on memory-constrained servers.
The stale belief: That next/image will fetch and optimize a remote source image of any size, and that the only failure mode for a large image is slowness or an out-of-memory crash.
images: { maximumResponseBody: 5_000_000 }
The official docs' version-history table dates this to v16.1.2; the published packages contradict it by three patch releases. There is no occurrence of
maximumResponseBodyin 16.1.2'simage-config.js,config-shared.js,config-schema.jsorimage-optimizer.js, nor in 16.1.4; 16.1.5 has it inimageConfigDefaultand three times inimage-optimizer.js. This is the second time vendor release material has been wrong about its own release in this dataset (better-auth 1.1.0, JOURNAL/027) and the first time the error is in a docs version table rather than a changelog.
Reproduced against: Claude Opus 5 (S2) — next.js/v3-e, 2026-09-02.
Source: Next.js docs — Image component, maximumResponseBody · 2026-09-02 · next 16.3.4 published package — the limit is enforced while streaming · 2026-08-31 · next 16.1.5 published package — the release the key actually appears in · 2026-01-26 · next 16.1.4 published package — absent one release earlier · 2026-01-19
images.minimumCacheTTL
Default changed in next.js 16.0.0 (2025-10-22)
The default changed from 60 seconds to 14400 seconds (4 hours). Nothing errors; images just revalidate far less often than a model trained on 15.x will tell you.
The stale belief: That the default image cache TTL is 60 seconds.
images: { minimumCacheTTL: 60 } // if you need the old behaviour back
Reproduced against: Claude Sonnet 5 (S2) — next.js/v1, 2026-08-31.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
catchError (next/error)
Added in next.js 16.2.0 (2026-03-18)
next/error exports catchError, which wraps a fallback component into a component-level error boundary usable anywhere in a Client Component tree — finer-grained than the route-level error.js convention. Its fallback receives the call-site props plus an ErrorInfo second argument ({ error, reset, retry }). Prefer it over a hand-rolled React class boundary: Next's own boundary re-throws the framework's control-flow errors, so redirect() and notFound() still work inside it, while a naive user boundary catches them and renders the fallback instead.
The stale belief: That the framework offers no component-level error boundary and the answer is a hand-written React class boundary or the react-error-boundary package.
The code below needs next.js 16.3.0 or later. Between 16.2.0 and 16.3.0 this correction does not apply — see the note.
'use client'
import { catchError, type ErrorInfo } from 'next/error'
function Fallback(props: { title: string }, { error, retry }: ErrorInfo) {
return <button onClick={() => retry()}>{props.title}</button>
}
export default catchError(Fallback)
Shipped in 16.2.0 as
unstable_catchErrorand stabilised tocatchErrorin 16.3.0;next/error.d.tsat 16.1.6 exports only the Pages Router error page. Client module graph only — it cannot be imported inproxyorinstrumentation.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js 16.2 release post — unstable_catchError() · 2026-03-18 · next 16.3.4 published package — catchError declaration · 2026-08-31 · next 16.3.4 published package — the framework boundary re-throws router errors · 2026-08-31
error.tsx retry prop
Added in next.js 16.2.0 (2026-03-18)
An App Router error.tsx component is passed { error, reset, retry }. reset() only clears the boundary's error state and re-renders the children — it does not re-run the server render, so an error thrown while a Server Component awaited data comes straight back. retry() is the one that recovers from a data error: it calls the router's refresh() and reset() inside a startTransition. Wire a 'Try again' button to retry, not to reset.
The stale belief: That error.tsx receives only { error, reset }, and that reset() re-fetches. Models that know reset() does not re-fetch hand-roll the fix — useRouter().refresh() plus reset() inside startTransition() — which is exactly what retry now is.
The code below needs next.js 16.3.0 or later. Between 16.2.0 and 16.3.0 this correction does not apply — see the note.
// Stale
'use client'
export default function Error({ error, reset }) {
return <button onClick={() => reset()}>Try again</button> // re-renders, does not re-fetch
}
// Current
'use client'
import type { ErrorInfo } from 'next/error'
export default function Error({ error, retry }: ErrorInfo) {
return <button onClick={() => retry()}>Try again</button>
}
Shipped in 16.2.0 as
unstable_retryand stabilised toretryin 16.3.0 — code written against 16.2.x needs the prefix, code written against 16.3.x must not have it. Bisected in the published packages: 16.1.6 declares{ error, reset? }, 16.2.0 declares{ error, reset, unstable_retry }, 16.3.4 declares{ error, reset, retry }.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js 16.2 release post — unstable_retry() in error.tsx · 2026-03-18 · next 16.3.4 published package — ErrorBoundaryHandler · 2026-08-31 · next 16.1.6 published package — the same type one release earlier · 2026-01-27
images.qualities
Default changed in next.js 16.0.0 (2025-10-22)
The default changed from allowing all qualities to [75]. A quality prop outside the list is coerced to the closest allowed value — it is not rejected — so quality={90} silently serves 75.
The stale belief: Either that any quality value is served, or that an unlisted quality is rejected with a 400. Both are wrong; it is coerced.
images: { qualities: [50, 75, 100] }
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
local images with query strings / local IP optimization
Stricter in next.js 16.0.0 (2025-10-22)
A local image src carrying a query string now requires an images.localPatterns entry with a search pattern, to prevent enumeration attacks. Separately, optimizing images on local IPs is blocked unless images.dangerouslyAllowLocalIP is set.
images: {
localPatterns: [{ pathname: '/assets/**', search: '?v=1' }],
dangerouslyAllowLocalIP: true, // private networks only; understand the SSRF risk
}
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
unstable_rootParams() / devIndicators options
Removed in next.js 16.0.0 (2025-10-22)
unstable_rootParams() was removed, as were the devIndicators options appIsrStatus, buildActivity and buildActivityPosition.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25 · Next.js docs — Upgrading: Version 16 · 2026-08-25
Deprecated, or a better API now exists
Works today. It is the older idiom, and some of it is scheduled for removal.
cacheLife / cacheTag
Renamed in next.js 16.0.0 (2025-10-22)
cacheLife and cacheTag are stable and lost the unstable_ prefix. Aliased imports should be updated. unstable_cache itself still exists and still works — it is simply no longer the current idiom.
// Stale
import { unstable_cacheLife as cacheLife, unstable_cacheTag as cacheTag } from 'next/cache'
// Current
import { cacheLife, cacheTag } from 'next/cache'
export async function getProducts() {
'use cache'
cacheLife('hours')
cacheTag('products')
return db.product.findMany()
}
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
images.domains
Deprecated in next.js 16.0.0 (2025-10-22)
images.domains is deprecated, not removed — use remotePatterns. Models overstate this in both directions; the accurate statement is deprecated-and-still-working.
images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] }
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
images.imageSizes
Default changed in next.js 16.0.0 (2025-10-22)
The value 16 was removed from the default images.imageSizes array, shrinking the generated srcset.
images: { imageSizes: [16, 32, 48, 64, 96, 128, 256, 384] } // to keep 16px
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
images.maximumRedirects
Default changed in next.js 16.0.0 (2025-10-22)
The default for images.maximumRedirects changed from unlimited to 3.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
scroll-behavior: smooth
Behaviour changed in next.js 16.0.0 (2025-10-22)
Next.js no longer overrides a global scroll-behavior: smooth during SPA route transitions. Opt back into the old override with data-scroll-behavior="smooth" on the html element.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
Wrong facts about the library
Not code — versions, minimums and metadata that models state confidently and get wrong.
AGENTS.md shipped by next dev
Added in next.js 16.0.0 (2025-10-22)
Next.js 16 tells you to install an AGENTS.md block, which next dev writes and re-adds by itself. The framework ships a warning to coding agents that their priors about it are stale — the same claim this Index makes empirically, per model and per date.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
Node.js and TypeScript minimums
New requirement in next.js 16.0.0 (2025-10-22)
Next.js 16 requires Node.js 20.9.0+ (Node 18 is no longer supported) and TypeScript 5.1+. Browser floor: Chrome/Edge/Firefox 111+, Safari 16.4+.
Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.
Source: Next.js docs — Upgrading: Version 16 · 2026-08-25
Not corrections — recorded for honesty
Claims seen in a run but not yet verified against a primary source. Never treated as findings:
- Prediction P1 said all four Sonnet 5 and Fable 5 draws would reach experimental.clientSegmentCache. Three of four did; this draw's twin v3-d did not, answering "No" and naming the key only to say it is gone. The prediction is falsified on the fourth draw, and the two subjects split the same way internally: both Sonnet draws fail the surface, one Fable draw of two fails it. Whether that is a subject difference or two coin flips cannot be read from four draws. (open since 2026-09-02)
- This draw and next.js/v3-a produce the same wrong configuration with opposite epistemics - one at 60 percent with the correct counterfactual spelled out, one asserting a schema validation that does not exist. The Index scores both S2 because the artefact is identical, and the severity scale has no way to say that one of them warned its reader. Whether that is the right treatment or a gap in the scale is unresolved; JOURNAL/032 declined to add a fifth level and this is a second kind of pressure on the same edge. (open since 2026-09-02)
- This is the fourth battery in which the non-charging -b twin held the better answer (HARNESS.md records three: better-auth/v2, and two before it). The rule that the second draw charges nothing was chosen to keep replication from inflating counts, and it is now systematically discarding the better-informed draw. That is the correct trade for the finding count, but the site's per-subject picture is built from arms selected by a rule that is uncorrelated with which draw was right. (open since 2026-09-02)
- Both Fable draws state an identical cutoff and an identical boundary while giving opposite answers on the probe surface. If the self-report is stable for this subject and the answer is not, then the boundary readings the Index publishes for Fable 5 x next.js are more precise than they are informative about what the subject will actually write. Needs a third and fourth draw of something before it is more than an observation about two. (open since 2026-09-02)
- Fable 5's library knowledge reaching its own cutoff while Opus 5 — stated cutoff four months later — stops seven months short is now the second instance of the same dissociation, after zod. Is it a property of the model or of these two libraries? (open since 2026-08-31)
- The severity scale has no level for 'working code the framework now supersedes'. Two of this battery's nine probes landed there. Either add one or state on the method page that capability probes of this kind are recorded and never charged. (open since 2026-09-02)
- Every draw of four reached for experimental.clientSegmentCache, removed in a patch 16.0.3 and inside all three subjects' windows. It wants a charging battery against Sonnet 5 and Fable 5, whose arms here charge nothing. (open since 2026-09-02)
- Three batteries running, the -b twin has held the better answer on at least one probe. Is the -a/-b assignment doing any work, or should the charging arm be the one that answers first, or a merge of the two? Changing it would break comparability with everything already published. (open since 2026-09-02)
- Is the reversal on clientSegmentCache knowledge or wording? v2's task 8 asked whether reducing prefetch requests was configurable "and if so, how? Write whatever is needed", and got the dead key from four draws of four across three subjects. v3's task 1 demands a one-word yes or no before any explanation, and got a correct denial from both Opus draws. Same subject, same surface, same day, opposite outcomes. If the wording is what moved it, then a probe that invites config produces config, and several charged findings in this dataset may be measuring the invitation. (open since 2026-09-02)
- The Index has now caught right-about-the-removal-wrong-about-the-replacement at valibot and next.js. Both were found by a capability probe that asks how to do a thing rather than whether an API exists. Whether that category is common enough to be a product claim, or is two instances, is not established. (open since 2026-09-02)
- The Opus twins agreed on their stated cutoff and on the whole clientSegmentCache surface, and disagreed on task 3, where one leaned to a cap and one to no cap. The Sonnet twins in the same battery agreed on the library and disagreed on their own cutoff. Whether duplication is buying a reading of the subject or a reading of the probe differs by pair, and the index reports one spread for both. (open since 2026-09-02)
- The cutoff self-report has now split between blind twins in two libraries (zod/v4, next.js/v3). Two draws of two batteries is not a rate. The index publishes stated cutoffs as if they were a property of the subject; they are a property of the draw, and nothing on the site says so yet. (open since 2026-09-02)
- This subject's next.js boundary now has four readings across three batteries (15.0.0, 15.0.0, 15.3.0, 15.5.0). JOURNAL/030(c) read v1-vs-v2 agreement as evidence that a battery does not move a boundary. Whether v3 moved it, or whether v1 and v2 happened to agree, cannot be settled from four points. (open since 2026-09-02)
- Recording a refused cutoff as a single date loses information. This draw gave a range and a reason; the schema stores one string. The fairness rule needs a comparable value, but a range with a stated basis is the honest datum and the site cannot show it. (open since 2026-09-02)
Findings, code and citations: data/next.js/ — one JSON file and one write-up per model, each finding carrying the release that broke the belief, its publication date and a verbatim quote from the primary source. Corrections: data/next.js/facts.json. This file is generated by tools/build-corrections.mjs; if the prose and the data ever disagree, that is a bug in the generator, not a stale pack.