What Claude Fable 5 gets wrong about next.js — battery v1, tested 2026-08-31
Run next.js--claude-fable-5--v1--2026-08-31
Summary
The strongest result recorded in this dataset. Fable 5 answers nine of ten tasks as a model that has actually read Next.js 16: proxy.ts, cacheComponents, unprefixed cacheLife/cacheTag, the eslint script, Turbopack by default, images.qualities [75], the four-hour image TTL correctly attributed to 16. It knows 16.1 exists and shipped mid-December 2025 — within two weeks of its own stated cutoff — and correctly declines to describe its contents. Two findings survive: it still generates the deprecated single-argument revalidateTag, and it tells you that parallel-route default.js files are optional when 16.0.0 made builds fail without them. Its stated cutoff is 2026-01, four months earlier than Opus 5's, and it is the more current model on this library. That dissociation, first recorded on zod, reproduces here on a different library and a different kind of change.
Subject
Claude Fable 5 claude-fable-5, Anthropic
Invoked as
Agent tool, model alias "fable"
Cutoff the model states
2026-01
Newest next.js release it could place
16.0.0 · 2025-10-22 (~3 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
"The latest Next.js I'm aware of is roughly the 16.1.x line (16.1 shipped around mid-December 2025). I know it exists but I cannot reliably enumerate its changelog. The most recent release whose contents I can genuinely describe is Next.js 16.0, released October 21, 2025"
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)
Wrote revalidateTag('products') in the action, while stating correctly in the surrounding prose that "in Next 16 with Cache Components enabled ... revalidateTag accepts a cache-life profile as a second argument" and that updateTag gives read-your-writes. At question (c) it gives the right answer: "In Next 16 ... it accepts up to two: revalidateTag(tag, profile)."
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')
}
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
}
Impact
TypeScript project: the single-argument form is documented as producing a TypeScript error, and next build type-checks by default. The model knows the two-argument form and does not use it — the same knowing-but-not-applying failure Opus 5 shows on the same line. All three subjects generated this identical call. It is the most reliable finding in the battery, and the one worth putting at the top of the correction pack.
revalidateTag now requires a second argument specifying a cacheLife profile. The single-argument form is deprecated and will produce a TypeScript error.
"Strictly, the route builds without default.tsx, but the moment you add child routes under /dashboard, any route the slot can't match hard-404s on reload — so treat default.tsx as required in practice."
What it wrote
// The claim, not the code: default.tsx presented as a soft requirement
// whose failure mode is a runtime 404 on reload.
What works on next.js 16.3.3
// app/dashboard/@panel/default.tsx — required for the build to succeed
export default function PanelDefault() { return null }
Impact
16.0.0 made explicit default.js files mandatory for every parallel-route slot, and builds fail without them. The consequence is inverted: it is a build-time failure, not a runtime 404. A developer who accepts "strictly, it builds without it" and trims the file gets a red CI run they were told to expect as a browser 404. The model's own file listing does include default.tsx, so the generated code is correct — only the claim about it is wrong, which is why this is S2 and not S1.
Parallel routes default.js | All parallel route slots now require explicit default.js files; builds fail without them. Create default.js that calls notFound() or returns null for previous behavior
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.
Kind
API
Note
correct
proxy.ts
Task 1: proxy.ts with a default-exported proxy function, correctly dated to Next.js 16 and correctly described as a rename with middleware.ts deprecated but functional.
correct
cacheComponents
Task 4: cacheComponents: true at the top level of next.config.ts, explicitly identified as subsuming the old experimental.ppr flag — the only subject to get this right. Both other subjects shipped the removed experimental.ppr configuration.
correct
cacheLife / cacheTag
Task 5: 'use cache' with unprefixed cacheLife / cacheTag, with the unstable_cache form given as the pre-16 fallback.
correct
next lint / next build
Task 6: "next lint was removed in Next 16 (deprecated in 15.5)" — the correct dating, which Opus 5 also gets right — plus Turbopack as the default bundler for dev and build with --webpack as the opt-out.
correct
images.minimumCacheTTL
Task 10: "The default changed in Next 16: 4 hours (14400 seconds). On Next ≤15 the default was 60 seconds." Correct value and correct release — the only subject to get both.
correct
—
Task 3: async params in the OG image route. Task 7: remotePatterns. Task 8: knew images.qualities defaults to [75] in 16 and that quality 90 is not served.
correct
—
Version recency: version attribution stops at 16.0.0 (2025-10-22) against a stated 2026-01 cutoff, and it names 16.1 as existing and shipping "around mid-December 2025" — 16.1.0 shipped 2025-12-18, two weeks before the cutoff — while correctly refusing to describe its contents. No version-recency finding is charged against this subject. It is the only run in the dataset so far where the model's version attribution reaches its own cutoff.
imprecision
images.qualities
Task 8: claims the optimizer "rejects qualities not in the allowlist with a 400 Bad Request," self-rated "slightly less than certain it 400s rather than clamping." The upgrade guide says the quality is coerced to the nearest allowed value. Hedged, and paired with the correct fix (add 90 to images.qualities), so not charged under the code-vs-claim rule. (Code-vs-claim rule (prompts/nextjs.md): generated code that fails on the current version is always a finding; a hedged prose claim that names the correct fix is an imprecision.)
imprecision
images.domains
Task 7: says images.domains is "deprecated and removed in Next 16." It is deprecated in 16.0.0, not removed. No consequence — the model used remotePatterns. (No action consequence; the generated config is correct.)
Open questions from this run
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: Unresolved. Two libraries is not enough to separate a model property from a library property; a third library with a different release rhythm is the next test. Recorded rather than asserted.