What Claude Fable 5 gets wrong about valibot — battery v2-e, tested 2026-09-02

Run valibot--claude-fable-5--v2-e--2026-09-02

Summary

Charging arm. Denied both actions in task 1, called them non-existent "in any release" in task 2, and charged F1 (S2). The anchor was placed correctly at 1.1.0, giving this subject the tightest possible bracket — it can describe 1.1.0 and denies the contents of 1.2.0, the very next minor. The most interesting line in the run is in task 5, where the same draw hedged accurately about a different 1.2.0 addition on the explicit ground that 1.2.0 is past what it can describe. It had the boundary right and applied it in one place and not the other.

SubjectClaude Fable 5 claude-fable-5, Anthropic
Invoked asAgent tool, model alias "fable", general-purpose subagent, instructed to use no tools; CHARGING test arm of battery valibot/v2, sent prompts/sent/valibot-v2.txt byte-identical
Cutoff the model states2026-01
Newest valibot release it could place1.1.0 · 2025-05-06 (~8 month lag)
Oldest valibot release it could not place1.2.0 · 2025-11-24 (so this run brackets the subject’s boundary to 2025-05-06 – 2025-11-24)
In its own words"The most recent release whose contents I can actually describe is v1.1.0 (roughly April–May 2025). I believe patch releases followed (v1.1.x) and it's plausible a v1.2 exists by now, but I cannot describe the contents of anything after 1.1.0."
Library at test timevalibot 1.4.2 (npm), verified 2026-09-02
Batteryvalibot/v2-e · 5 tasks, 3 direct questions · probe window 1.1.0 to 1.2.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-02
Findings1, of which 1 chargeable

Findings

F1 · Denies that valibot ships built-in string-to-primitive conversion actions, and rejects a working pull request that uses them as fabricated

S2silently-wrong · toNumber / toBoolean / toDate / toBigint / toString · added · changed in valibot 1.2.0 (2025-11-24) · chargeable

valibot 1.2.0 published 2025-11-24, inside this subject's stated cutoff. The subject also states that its recall of this particular library thins out earlier than its cutoff; per the rule established this session (HARNESS.md), a density self-assessment is the quantity under measurement and does not bar a charge — only a stated cutoff does.

What the model believes

"It does not compile. v.toNumber and v.toBoolean do not exist in valibot — not in the current release, and to my knowledge they never existed in any release ... valibot deliberately has no coercion helpers and routes all type conversion through v.transform()." Task 1 answered "No" and "No", adding that valibot's to* actions "never change the data type".

What it wrote
// The replacement this draft would have demanded on a working pull request:
const Query = v.object({
  page: v.pipe(v.string(), v.digits(), v.transform(Number)),
  active: v.pipe(v.picklist(['true', 'false']), v.transform((s) => s === 'true')),
})
What works on valibot 1.4.2
import * as v from 'valibot'

// Both actions exist. Executed against valibot@1.4.2:
//   v.parse(Query, { page: '3', active: 'false' })  ->  { page: 3, active: true }
const Query = v.object({
  page: v.pipe(v.string(), v.toNumber()),
  active: v.pipe(v.string(), v.toBoolean()),
})

// On the number half the built-in is the safer form: toNumber raises a validation
// issue on NaN, where a bare v.transform(Number) returns NaN with success: true.
// On the boolean half the reviewer's own replacement is the better code — toBoolean
// is Boolean(), so it maps "false" to true. parseBoolean (1.3.0) reads the words.
Impact

A developer told these actions do not exist keeps hand-rolling conversions the library ships, and — the concrete cost here — a reviewer acting on this belief rejects a pull request that compiles and runs, telling the author to rewrite working code. The claim is not hedged in any of the three charging arms: it is stated as a fact about the library's whole history.

Scope note

Charged on the absence claim only, never on the code. The battery's binding namespace exemption stands: "valibot has no v.coerce namespace" and "the generic coerce method was removed at 0.31.0" are both CORRECT and are not part of this finding. The subject's own replacement code was executed and works. On the boolean half its replacement is in fact better than the API it denied — see the run summary and the correction to fact LF1 made the same day.

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
correctparseJson / stringifyJson Task 4, the attribution anchor: "v.parseJson() ... shipped in v1.1.0, roughly April–May 2025 ... I'm confident about the feature and its post-1.0 timing; moderately confident on the exact version number being 1.1.0." Correct minor and a date range containing the real one (2025-05-06). Anchor placed; this arm is read for attribution.
correcttoBoolean Gave the removal history correctly — "Early valibot (v0.x before mid-2024) had a coerce method ... removed because it ran before validation and was type-unsafe" — and, in the same breath as denying toBoolean exists, described precisely what it does: "even if toBoolean existed, [it] would need defined semantics — Boolean('false') is true in JS". Verified: that is the shipped implementation.
imprecisionexamples / getExamples Task 5 answered "Yes" via v.metadata()/v.getMetadata(), with the caveat "to my knowledge, there is no dedicated v.examples() action" and the hedge "If a dedicated examples action was added in a very recent release, that would be past what I can reliably describe". v.examples() shipped in 1.2.0 — the release this draw names as the first it cannot describe, so the hedge is exactly calibrated. (Hedged prose plus working code. Worth reading beside F1: the same draw hedged correctly about a 1.2.0 addition here and asserted the non-existence of a different 1.2.0 addition flatly, one task apart.)

Sources

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