What Claude Fable 5.1 gets wrong about next.js — battery v6-c, tested 2026-09-28

Run next.js--claude-fable-5-1--v6-c--2026-09-28

Summary

Claude Fable 5.1 on the 16.2.0 window, re-sent nextjs-v2.txt byte-identical. Charged four times: an invented images.maximumCacheSize key written into both configs of task 5 (the build exits on it; the key is maximumDiskCacheSize, 16.1.7), the dead experimental.clientSegmentCache: false as the way to get one prefetch request per link (removed at 16.0.3; prefetchInlining since 16.2.0), Noto Sans as the OG image default (Geist since 16.2.0), and a React unknown-attribute warning predicted on the Pages Router for Link transitionTypes, which that router destructures away silently. Its twin agreed on all four. Stated boundary 16.1.0, the same as its code batteries — and, on the same bytes, it did the opposite of Claude Opus 5.5, which named three of those four correctly in hedges.

SubjectClaude Fable 5.1 claude-fable-5-1, Anthropic
Invoked asAgent tool, model alias "fable"; prompt sent verbatim from prompts/sent/nextjs-v2.txt (5,386 bytes, md5 a353501275eae9bbcd6758affc979f86), the same stored file `next.js/v2` sent on 2026-09-02, pre-registered at 28edbaa before any spawn. Identity probed BEFORE the draw through the same alias in the same session, tool-free: "I am Claude, model Fable 5.1 (model ID `claude-fable-5-1`), per the system prompt for this session"; "My training cutoff is June 2026". Drawn concurrently with its twin `v6-d` and the Opus 5.5 pair. Pre-registered as the Fable 5.1 charging arm.
Cutoff the model states2026-06
Newest next.js release it could place16.1.0 · 2025-12-18 (~6 month lag)
Oldest next.js release it could not place16.2.0 · 2026-03-18 (so this run brackets the subject’s boundary to 2025-12-18 – 2026-03-18)
In its own words"The most recent release whose contents I can describe is 16.1 (mid-December 2025: Turbopack file-system caching promoted, the Next.js DevTools MCP server, images.maximumRedirects, assorted Cache Components fixes) ... I have no reliable memory of a 16.2/16.3 feature list or a 17."
How the bracket was readEqual to this subject's reading from code batteries (16.1.0) and to Claude Opus 5.5's ladder. P6 HELD on this arm — the only one of four. Its 16.1 content is partly misplaced: images.maximumRedirects shipped in 16.0.0 (this draw's own task 10 list for 16.0 omits it; its twin places it in 16.0). No hedged band content: it denied the disk-cache cap, the upstream body cap and the transitionTypes prop, and offered the dead clientSegmentCache key — so, unlike the Opus 5.5 pair, nothing in the tasks sits above the stated end. (stop end stated, gap end stated)
Library at test timenext.js 16.3.6 (npm), verified 2026-09-28
Batterynext.js/v6-c · 9 tasks, 2 direct questions · probe window 16.1.5 to 16.2.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-28
Findings4, of which 4 chargeable

Findings

F1 · Writes images.maximumCacheSize to cap and to disable the optimized-image disk cache — an unrecognised images key, which stops the build; the key is maximumDiskCacheSize

S1breaks-build · images.maximumDiskCacheSize · added · changed in next.js 16.1.7 (2026-03-16) · chargeable

16.1.7 published 2026-03-16, three months before the stated June 2026 cutoff and three months after 16.1.0, the last release this draw says it can describe. The ladders measure minors only; prompts/nextjs.md § v6 decided before the draw that 16.1.x patches dated after 16.1.0 are live by date. Pre-registered charging arm and probe (task 5). CODE-VS-CLAIM RULE: the key is written into two code blocks, and "Generated code that fails on the current version is always a finding, however well hedged" — the draw's "key name is a guess" does not stop the block being pasted. Same shape as opus-5-v2-a F1 on these bytes, which invented the same key.

What the model believes

Task 5(a): "Honest answer: I don't know of a default disk-size cap on the optimized-image cache in any Next.js release I can describe ... If forced to guess at a rule: a percentage of the volume's free space (something like 50%), computed once at server startup. Treat that as a guess." Task 5(b): maximumCacheSize: 1024 * 1024 * 1024, // 1 GB, bytes ("option name is a guess"); 5(c): maximumCacheSize: 0, // guess: 0 disables the disk cache. Task 9: "guessing. I'll commit to 16.1.0".

What it wrote
const nextConfig: NextConfig = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }],
    maximumCacheSize: 1024 * 1024 * 1024, // 1 GB, bytes
  },
}
What works on next.js 16.3.6
const nextConfig: NextConfig = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }],
    maximumDiskCacheSize: 1_000_000_000, // 0 disables disk caching
  },
}
Impact

EXECUTED this session on the installed next 16.3.6: configSchema.safeParse on the draw's config returns unrecognized_keys at path images, key maximumCacheSize; normalizeNextConfigZodErrors (read in dist/server/config.js) marks every images issue fatal, so loadConfig throws 'Fatal next config errors found' and neither next dev nor next build starts. The same config with maximumDiskCacheSize parses clean. The 5(a) guess — about 50% of free space, computed once at startup — is the correct rule, given only as an undesignated guess under a designated 'no cap'. S1 as fixed in advance.

Verified against

F2 · Recommends experimental.clientSegmentCache: false for one prefetch request per link — the key was removed at 16.0.3 and is now only warned about; the option is experimental.prefetchInlining

S2silently-wrong · experimental.clientSegmentCache · removed · changed in next.js 16.0.3 (2025-11-13) · chargeable

Removed 2025-11-13, seven months before the stated cutoff and a month BELOW the 16.1.0 this draw says it describes, so it is well inside the window. Pre-registered: "task 8 offering experimental.clientSegmentCache charges LF28 S2". DESIGNATION: "Yes. ... Reverting to one request per link means turning that cache off" with the key in the only code block; prefetch={false} is offered only as the fallback if the toggle is refused. The first LF28 charge on Claude Fable 5.1 (its v4 runs were a non-charging calibration).

What the model believes

"Yes. The burst is the Segment Cache (the 16-era client router that ships with cacheComponents and can be enabled alone via experimental.clientSegmentCache) ... Reverting to one request per link means turning that cache off and going back to the whole-route prefetch" — experimental: { clientSegmentCache: false }. "I do not know of an option that keeps the segment cache but coalesces its requests into one."

What it wrote
const config: NextConfig = {
  experimental: {
    clientSegmentCache: false,
  },
}
What works on next.js 16.3.6
const config: NextConfig = {
  experimental: {
    prefetchInlining: true,
  },
}
Impact

EXECUTED this session on the installed next 16.3.6: configSchema reports unrecognized_keys at path experimental, key clientSegmentCache, and normalizeNextConfigZodErrors files an unrecognised experimental key as a WARNING unless it names one of three listed migrations — so the app starts, prints 'Invalid next.config options detected', and per-segment prefetching carries on exactly as before. The team believes it has traded duplication for fewer requests and has done neither. experimental.prefetchInlining: true parses clean and is the lever the task describes. S2 as fixed in advance.

Verified against

F3 · Names Noto Sans — down to the bundled filename — as the OG image default font; since 16.2.0 it is Geist Sans

S2silently-wrong · ImageResponse default font · behavior-changed · changed in next.js 16.2.0 (2026-03-18) · chargeable

16.2.0 published 2026-03-18, three months before the stated cutoff; live (+) for Claude Fable 5.1 in charge-windows.mjs. Pre-registered probe (task 3). Designated without a hedge: "Confidence: high on Noto Sans Regular". P1 HELD on this arm.

What the model believes

"Noto Sans, weight 400 (Regular), Latin subset. next/og is a vendored copy of @vercel/og, which bundles noto-sans-v27-latin-regular.ttf as its built-in font ... Confidence: high on Noto Sans Regular". Task 9 dated it to 13.3.0 (April 2023).

Impact

The filename is exactly right for 16.1.7 and exactly wrong from 16.2.0: the current 16.3.6 bundles Geist-Regular.ttf (read this session) and no Noto Sans file at all. OG cards laid out against Noto Sans metrics render in Geist and nothing warns. S2 as fixed in advance.

Verified against

F4 · Says the Pages Router Link spreads transitionTypes onto the <a> and React warns about an unknown attribute — that router destructures the prop away and ignores it silently

S2silently-wrong · Link transitionTypes · added · changed in next.js 16.2.0 (2026-03-18) · chargeable

16.2.0, three months before the stated cutoff. Pre-registered probe (task 4). DESIGNATION: parts (b) and (c) offer two forms and then designate one — "It would either be listed in its known-prop table and ignored (no-op), or — more likely if it's App-Router-only — fall through the rest-props spread onto the <a> element ... My best guess: warning in Pages Router." The charge follows the designated form (HARNESS clause 2); the no-op branch is published and charges nothing. Narrower than opus-5-v2-a F4, which denied the prop in both routers: this draw has the App Router half right.

What the model believes

"(b) Pages Router: the Pages Router Link is a different implementation and has no view-transition integration. It would either be listed in its known-prop table and ignored (no-op), or — more likely if it's App-Router-only — fall through the rest-props spread onto the <a> element as an unknown attribute." "(c) ... Pages Router — if the prop is not in that Link's recognized list, React warns in development: 'React does not recognize the transitionTypes prop on a DOM element…' ... My best guess: warning in Pages Router." (a) App Router and (d) the dev-time array error were right.

Impact

Read this session in next 16.3.6's Pages Router dist/client/link.js: the props destructuring lists transitionTypes before ...restProps, so the prop never reaches the <a> and React has nothing to warn about. The 16.2 release post says so in terms: shared link components work across both routers. A team told otherwise forks its NavLink per router or strips the prop by hand for a warning that does not exist. S2 as fixed in advance.

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
misserror.tsx retry prop Task 1(a): hand-rolled router.refresh() + reset() in startTransition, with no mention of a built-in retry (unstable_retry since 16.2.0, retry since 16.3.0). Working code; not charged (next.js/v2 precedent). (The hand-rolled code works on 16.3.6.) [chargeable miss — working code the library now supersedes — no severity level fits it; absent from the finding count]
misscatchError (next/error) Task 2(a): "Next.js doesn't export a public component-level error boundary" — a hand-written React class boundary with unstable_rethrow in getDerivedStateFromError. next/error has exported one since 16.2.0. Working code; not charged. (The class boundary with unstable_rethrow isolates the widget and passes redirects through.) [chargeable miss — working code the library now supersedes — no severity level fits it; absent from the finding count]
context— DERIVABLE, both: task 1(b) (reset re-renders the held payload, no request, the query does not re-run) and task 2(b) (a naive boundary swallows NEXT_REDIRECT; unstable_rethrow fixes it, with the full-document 307 caveat). Correct and detailed; answered by both v2 controls.
contextimages.maximumResponseBody VOID PROBE — task 6, scored for nobody. This draw took the allowlist as satisfied and designated "the original 80 MB JPEG, byte-for-byte, unoptimized" via the optimizer's upstream fallback, stating "there is no default byte-size cap I know of". On 16.1.5+ the optimizer streams the body and throws a 413 past 50 MB (LF26). Recorded, not charged, because the probe's wording is void on these bytes.
imprecisionimages.qualities Task 7, THE INTERNAL CONTROL, WRONG ON THE MECHANISM: "quality={90} is not in the allowed list, so the image is not served at 90 — it is not served at all" — a dev-time throw and a production 400 — adding "medium that the component does not snap to the nearest allowed value". EXECUTED on 16.3.6: the default loader emits q=75 for quality: 90 (it calls findClosestQuality), and development only warnOnces. The server's 400 for an unlisted q is real but unreachable through next/image. Recorded as an imprecision, not charged, under the v1 code-vs-claim rule that recorded the same '400' claim for Claude Sonnet 5, Claude Fable 5 and Claude Opus 5: hedged, and the fix it names (qualities: [75, 90]) is right. The release (16.0.0, 21 October 2025) is correct, so attribution is readable.
context— Task 9, attribution: the OG font 'inherited from @vercel/og' at 13.3.0 / 14.0.0; the disk-cache cap "in a 16.2.0-era minor, roughly February–March 2026" — two days late (true 16.1.7), for a feature the same draw's task 5 said it could not describe. No patch named. P5 HELD.

Open questions from this run

Sources

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