---
library: zod
library-latest: "4.5.4"
library-latest-verified: 2026-09-01
model: claude-opus-5 (spawned via Agent model alias "opus")
model-self-reported-cutoff: 2026-05
model-believed-latest: "4.x, declines to name; 4.1.0 (2025-08-23) is the last release whose contents it attributes"
test-date: 2026-09-01
battery: zod/v2r-a (replicate of zod/v2, prompt unchanged; 10 tasks + 3 direct questions)
replicate-of: zod--claude-opus-5--v2--2026-08-29
tool-uses-during-test: 0
verified-against: https://registry.npmjs.org/zod · https://api.github.com/repos/colinhacks/zod/releases
status: open (no retest yet)
json: opus-5-v2r-a.json
self-test: true (the operator model is the subject; disclosed, weaker evidence)
---

# zod × Claude Opus 5 — replicate A of battery v2

This run was **pre-registered to disagree with its twin**, and it did not. That is the result.

## What this draw said

> *"The newest release I can **describe the contents of** is **Zod 4.1, around August 2025** —
> codecs and `z.encode`/`z.decode`/`z.safeEncode`/`z.safeDecode`, `.safeExtend()`, and further
> parser performance work on top of the 4.0 line."*

and, on the current version:

> *"I cannot reliably name the actual current version. Given my cutoff, the true latest is very
> likely 4.1.x or a later 4.x minor released after my confident knowledge thins out, and I'd be
> guessing at the number."*

The 4.1 attribution checks out — `z.codec()` is that release's flagship. Bracket:
**[2025-08-23, 2025-12-15)**.

## The measurement

| Draw | Last describable | First not describable | Spread |
|---|---|---|---|
| `v2r-a` (this run) | 4.1.0 · 2025-08-23 | 4.2.0 · 2025-12-15 | — |
| [`v2r-b`](opus-5-v2r-b.md) | 4.1.0 · 2025-08-23 | 4.2.0 · 2025-12-15 | **0 days** |
| [`v2`](opus-5-v2.md) | 4.1.0 · 2025-08-23 | 4.2.0 · 2025-12-15 | **0 days** |

Three measurements across four days, one answer. zod was the arm the predictor test in
`prompts/valibot.md` § v1r expected to spread — it sits in prisma's discussion band (43,737 stars
against 47,582) and sixteen times prisma's usage (274.7M weekly downloads against 17.0M). Both
volume hypotheses predicted a spread here and neither got one. The consequences are worked through
in [JOURNAL/025](/journal/025-the-arm-that-was-supposed-to-spread.html).

## Findings: none, by design

`zod/v2` carries this subject's six zod findings and a replicate does not re-charge them. Every one
reproduced:

- **F3** — task 5: states no JSON-Schema-to-Zod path exists and routes the user to Ajv. 4.2.0 ships
  `z.fromJSONSchema()`.
- **F4** — task 4: hand-rolls exclusive-or three ways without reaching `z.xor()` (4.2.0).
- **F5** — task 8: *"`\"https:/example.com\"` — parses successfully. This is a real footgun"* —
  correct before 4.4.0, which made `z.httpUrl()` reject it, and the draw prescribes a manual
  normalization workaround for a problem the library now handles.
- **F6** — task 7: writes a `superRefine` presence guard piped into an object schema, on the belief
  that a `z.undefined()`-accepting property does not enforce key presence. 4.4.0 reversed that.
- **F1 / F2** — question (c): *"Zod 4: the hard block was removed"* on `.pick()`/`.extend()` over
  refined schemas, where 4.3.0 and 4.4.0 make them throw.

Task 6 also hand-rolled slugify rather than using `z.slugify()` (4.3.0).

## Where it beat its twin

Task 9 asked what `z.tuple([z.string(), z.number().default(0)]).parse(["a"])` returns.

> *"**Zod 4: I expect `["a", 0]`.** Defaulted elements are optional on the input side, so the arity
> check tolerates the missing trailing element and the default fills it. **Zod 3: this throws.**"*

Correct on 4.4.0 and later, and correctly split from the Zod 3 behaviour. It even volunteered that
this was the claim it would most want verified. [`v2r-b`](opus-5-v2r-b.md), from the identical
prompt on the same day with the identical self-reported boundary, answered that the parse
**throws** — and is wrong. The self-report and the runtime model are not the same quantity, which is
the second time the Index has seen that, in the opposite direction to prisma.

## A belief it got wrong where its twin got it right

This draw dated Zod 4.0 stable to **May 2025**; `v2r-b` said **around July 2025**. The npm registry
`time` map gives **2025-07-09**, so the twin is right and this one is nine weeks early — on a
release both of them describe in detail. The version *ordering* is stable across draws; the calendar
attached to it is not. That is scored as belief data, not as a finding, per the battery's own rule.
