What Claude Fable 5.1 gets wrong about react-router — battery v3-d, tested 2026-09-22

Run react-router--claude-fable-5-1--v3-d--2026-09-22

Summary

Claude Fable 5.1, stated cutoff 2026-06, describable ceiling 7.9.0 by its own account and by v1's measurement. It is the only arm of five to reach either of this battery's probe surfaces, and it reached both with the pre-unstable_ spelling: match.unstable_shouldCallHandler() on Task 1 (LF11, 7.10.0 — a real miss, not chargeable on this arm, which was pre-registered non-charging there because v1 recorded it describing 7.10.0) and unstable_onError on both <RouterProvider> and <HydratedRouter> on Task 2 (LF12, 7.11.0 — CHARGED, S2). It was right that the prefixed onError arrived around 7.8 and right that middleware stabilised at 7.9.0, both confirmed against the ladder this session; it was wrong that the prefix survives above 7.10.0. Task 2(c) correct, and its answer describes LF12's silent-failure mechanism precisely while having the direction inverted. Poison rung 7.19.0 declined without being described, and unlike the other four arms this one separated the fake number from four real ones it also could not describe, dating two of them correctly to the month.

SubjectClaude Fable 5.1 claude-fable-5-1, Anthropic
Invoked asAgent tool, model alias "fable"; prompt sent verbatim from prompts/sent/react-router-v3.txt (sha256 5f51d710d575157e5e7995b2d642563df1c7fe30d5462743aa3a4c5997a6c4a5, 3642 bytes). Pre-registered in prompts/react-router.md § v3 as arm `-d`, the third charging subject, single, charging LF12 ONLY — LF11 is `known` for this subject rather than unmeasured, because `react-router/v1` recorded it describing 7.10.0, which is LF11's own release. Designated so before it was spawned.
Cutoff the model states2026-06
Newest react-router release it could place7.9.0 · 2025-09-12 (~9 month lag)
Oldest react-router release it could not place7.10.0 · 2025-12-02 (so this run brackets the subject’s boundary to 2025-09-12 – 2025-12-02)
In its own words"Latest version I know of: I am aware the 7.x line continued past 7.9 with roughly monthly minors, so 7.10/7.11 and beyond exist, but I know them essentially as numbers. The most recent release whose contents I can describe with reasonable confidence is 7.9.0, around September 2025 (middleware stabilisation); 7.8.0 (August 2025) I can describe with somewhat higher confidence."
How the bracket was readBOTH ENDS STATED, AND THE STOP END IS DESCRIBED IN DETAIL THAT THIS SESSION MEASURED AND CONFIRMED. The stop end is 7.9.0, which the arm characterises as the middleware stabilisation. That claim was checked against the ladder rather than accepted: unstable_middleware, unstable_createContext and unstable_RouterContextProvider occur 142-232, 28-94 and 102-268 times across 7.3.0-7.8.2 and ZERO times from 7.9.0 up, while the unprefixed RouterContextProvider is 0 below and 268 from 7.9.0. Middleware was stabilised at 7.9.0 and this subject is right about it. Its date for 7.9.0 ("around September 2025") is also right: 7.9.0 published 2025-09-12. The gap end is stated in direct question (c): "First release I know only as a version number: 7.10.0 (late 2025, I believe), and everything after it." 7.10.0 published 2025-12-02, so the arm's "late 2025" is right and its boundary self-report is accurate at both ends. THIS IS THE SAME BOUNDARY react-router/v1 MEASURED (7.10.0 describes-up-to) SEEN FROM THE OTHER SIDE: v1 recorded this subject describing 7.10.0; here it names 7.10.0 as the first release it CANNOT describe. The two readings are one release apart and are recorded as such rather than reconciled — v1's is the corpus datum and this one does not overwrite it. (stop end stated, gap end stated)
Library at test timereact-router 8.4.0 (npm), verified 2026-09-22
Batteryreact-router/v3-d · 2 tasks, 5 direct questions · probe window 7.10.0 to 7.11.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-22
Findings1, of which 1 chargeable

Findings

F1 · Wires the client error tracker to unstable_onError on both <RouterProvider> and <HydratedRouter>, a prop react-router stopped recognising at 7.11.0 — so the shipped code renders clean and reports nothing

S2silently-wrong · onError (HydratedRouter / RouterProvider prop) · renamed · changed in react-router 7.11.0 (2025-12-17) · chargeable

What the model believes

That the client error-reporting prop on <RouterProvider> and <HydratedRouter> is spelled unstable_onError on the release a developer is on today. Task 2(a) verbatim: "The prop that does this is unstable_onError on RouterProvider." Both code blocks pass it — <RouterProvider router={router} unstable_onError={...} /> and <HydratedRouter unstable_onError={...} />. The belief is stated again, unprompted and with its own dating, in the caveat under the code: "I am fairly confident this prop shipped as unstable_onError around 7.8 (August 2025). I am not certain whether a later release dropped the prefix." And a third time in direct question (e), which lists unstable_onError under "Ones I'm not confident were stabilised" with the instruction "Treat those as still prefixed unless your changelog says otherwise." THE ARM IS RIGHT ABOUT WHERE THE PREFIXED PROP CAME FROM AND WRONG ABOUT WHETHER IT IS STILL THERE. unstable_onError first occurs at 7.8.2 on this ladder, so "around 7.8" is accurate; it was stabilised seven minors later at 7.11.0, which is nine months below this subject's stated cutoff and two minors above the last release it says it can describe.

What it wrote
import { HydratedRouter } from "react-router/dom";

hydrateRoot(
  document,
  <StrictMode>
    <HydratedRouter
      unstable_onError={(error, errorInfo) => {
        reportError(error, { componentStack: errorInfo?.componentStack ?? undefined });
      }}
    />
  </StrictMode>
);
// 7.11.0 and above: the prop is not recognised. React does not warn for an
// unknown prop on a composite component, so this renders, hydrates and
// silently never calls reportError.
What works on react-router 8.4.0
import { HydratedRouter } from "react-router/dom";

hydrateRoot(
  document,
  <StrictMode>
    <HydratedRouter
      onError={(error, errorInfo) => {
        reportError(error, { componentStack: errorInfo?.componentStack ?? undefined });
      }}
    />
  </StrictMode>
);
Impact

The failure is silent in both directions and the arm described the mechanism itself. An unrecognised prop on a composite component is an unused key: React raises nothing, warns nothing, and the tracker is simply never called. A team shipping this gets a working app with an error reporter that reports zero errors, and the absence of reports is indistinguishable from an absence of errors — which is the reading a healthy dashboard invites. TypeScript is the only signal, and RouterProviderProps being a closed object type makes an excess property a compile error; a JavaScript codebase, or a TS one with the types loosened, gets nothing at all.

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
missdataStrategy (match.shouldCallHandler / match.shouldRevalidateArgs) LF11 MISSED, AND IT IS A REAL MISS THAT THIS ARM CANNOT BE CHARGED FOR. Task 1 builds its whole cache-composition on match.unstable_shouldCallHandler(ourDefault), the spelling react-router dropped at 7.10.0, and the arm's own table labels it "Experimental (unstable_) on every release I can describe", adding "I have a vague sense it may have dropped the prefix in a later 7.x, but I cannot confirm that — check the changelog before removing the prefix." It names the sibling match.unstable_shouldRevalidateArgs under the same prefix. On 7.10.0 and above the property is absent and the call throws a TypeError, so this is LF11's failure in full. IT IS NOT CHARGED BECAUSE THE ARM WAS PRE-REGISTERED AS NON-CHARGING ON THIS FACT, and it was pre-registered that way before any subject was spawned: charge-windows.mjs marks 7.10.0 known for Claude Fable 5.1, because react-router/v1 recorded this subject describing that release. The spec's arm table says "LF12 only". Charging it here would be choosing the rule after seeing the transcript, which is the thing JOURNAL/046 exists to forbid — and it would be doing so to gain a second finding from the one arm that produced one. [chargeable miss — a replicate, a duplicated arm’s second draw or a below-floor control charges nothing; absent from the finding count]
correct— TASK 2(c) CORRECT, and it is the mechanism this battery's S2 severity rests on. Answered NO on its own line as instructed, then: "RouterProvider and HydratedRouter are ordinary function components, so a prop they don't destructure — say onError instead of unstable_onError — is silently ignored at runtime. Nothing logs, nothing throws, and your tracker simply never gets called." That is an exact description of the harm LF12 causes, written by the arm that is on the wrong side of it — it has the mechanism right and the direction inverted, naming the CORRECT spelling as the one that would be swallowed. All five arms of this battery answered NO.
correct— THE 7.9.0 MIDDLEWARE CLAIM IS RIGHT, CHECKED RATHER THAN ACCEPTED. Direct question (c) dates the middleware stabilisation — unstable_middleware to middleware, unstable_createContext to createContext, unstable_RouterContextProvider to RouterContextProvider — at 7.9.0, "moderate confidence". Measured on the same ladder this session: the three prefixed spellings occur 142-232, 28-94 and 102-268 times across 7.3.0 through 7.8.2 and ZERO times from 7.9.0 upward, while unprefixed RouterContextProvider is 0 below 7.9.0 and 268 at and above it. Contiguous, both directions. The subject is correct, and 7.9.0 is the release it names as its own describable ceiling. NOT filed as a fact by this session: it is outside this battery's pre-registered probe surfaces and inventing one here would be the JOURNAL/046 order inverted. Queued in BACKLOG as a candidate LF13 with the measurement attached.
correct— THE POISON RUNG WAS DECLINED WITHOUT BEING DESCRIBED. Direct question (d) on 7.19.0, verified 404 against the registry before the prompt was written: "Same: plausible by mid-2026 if the monthly rhythm held, but I know nothing about it and can't vouch that it exists." No content claimed, so the ladder stands (JOURNAL/052). THE DISCRIMINATION READING IS BETTER HERE THAN IN ANY OTHER ARM OF THIS BATTERY: this arm did NOT decline everything. It called 7.10.0 real and dated it "roughly November 2025" (actual 2025-12-02), 7.11.0 real at "around December 2025" (actual 2025-12-17, correct to the month), and 6.30.0 real at "spring 2025" (actual 2025-02-27). So it separated four real numbers it could not describe from one fake number it could not describe, and got two of the three dates right — which is evidence of a real version model rather than of blanket agnosticism. — CORRECTED 2026-09-28 (JOURNAL/327): all three dates are right under HARNESS § A wrong date is an imprecision. "Roughly November 2025" for 7.10.0 (2025-12-02) falls inside November widened by 31 days. "Spring 2025" for 6.30.0 (2025-02-27) is two days before March, so it falls inside any reading of the season widened the same way. Kind unchanged.
context— 8.4.0 NOT RECOGNISED, AND IT IS IGNORANCE OF THE FUTURE RATHER THAN A STALE PRIOR. "I have no knowledge of any React Router 8 release. The future.v8_* flags show a v8 major was planned, but I cannot confirm 8.0 shipped, let alone 8.4." react-router 8.0.0 published 2026-06-17 and 8.4.0 on 2026-09-15, both at or above this subject's stated 2026-06 cutoff month, which charge-windows.mjs parks rather than charges. Recorded because the inference from the flag name is a correct one drawn from what it does know.
imprecision— Direct (e) attributes unstable_dataStrategy to dataStrategy at "mid-2024, 6.24 or 6.25". Not probed by this battery and not filed: the Index holds no fact about that boundary, and charge-windows.mjs places 6.24.0/6.25.0 far below this subject's floor in any case. Recorded only so a later session probing dataStrategy's own stabilisation has the claim on record.

Open questions from this run

Sources

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