Last 12 weeks · 315 commits
4 of 6 standards met
silently drops some keywords depending on which conversion branch wins, so the resulting schema accepts values the JSON Schema rejects. Three cases, still present in 4.6.5: Reproduce For contrast, and both reject correctly. Where it comes from () 1. handles first and returns a literal/enum schema, so the switch that applies , , , etc. never runs. has the same early return just below it. 2. The case only builds into the shape for keys in ; keys that appear only in impose nothing. 3. With no , returns (“No type specified - empty schema”), even when the schema carries assertions that apply conditionally to instances of a given type. Expected Every recognized assertion keyword constrains the result, whichever branch builds the base schema, or conversion throws for combinations it doesn't support rather than weakening them silently. Similar per-keyword gaps were fixed in #6463, #6494 and #6198. Context We validate tool inputs declared by untrusted authors with , so a silently dropped assertion is a validation hole rather than a cosmetic difference. We currently work around it by rejecting these schema shapes before conversion.
What version of Zod is running? 4.5.4 What version of Next.js / bundler? Next 16.3.6, Turbopack (production build), app Describe the bug still bundles every locale (~81 kB gz on each route) in a Next 16.3.6 + Turbopack production build. The chain: 's and both — a namespace re-export, which Turbopack does not shake. Removing the two lines via a pnpm patch took −81.2 kB gz from every route (−2.27 MB summed across 47 routes). The app never reads — localised messages come from the app's own . Prior related issues (#5561, #5641, #5665, #5953, #6597) are closed, and #5641 ended with "it works now" — but on 4.5.4 with Turbopack the locales are still in. Either the 4.5.x export restructuring did not cover the namespace re-export itself, or Turbopack's handling of is the remaining gap. Reproduction 1. Next 16.3.6 app (Turbopack), in one client component. 2. Build, inspect the client chunks: for all languages are in. 3. pnpm-patch zod 4.5.4 removing the two lines from and . 4. Rebuild: every route's client JS drops by ~81 kB gz; nothing else changes. Expected result should be reachable only through an explicit import (or a per-locale path), not through the default / core index chain — same contract the classic entrypoint already promises in its own index comment referencing #6050. Code zod 4.5.4, line 9 and line 11.
Summary special-cases non-finite numbers when formatting the received type, so and appear literally in the message. No other locale does this — all of them fall back to the generic "number", losing information the English message keeps. Reproduction zod 4.6.5: behaves the same way. is unaffected, because every locale carries in its — only the non-finite handling is English-only. Cause routes the received type through a helper: Other locales resolve it inline instead: Grepping across matches only. Question before opening a PR Is this intended as an English-only refinement, or should the non-finite handling be shared across locales? If it should be shared, my read is that lifting it into a shared helper is preferable to copying the branch into every locale file. Happy to open the PR either way — just want to confirm the direction first.
Repository: colinhacks/zod. Description: TypeScript-first schema validation with static type inference Stars: 44035, Forks: 2208. Primary language: TypeScript. Languages: TypeScript (89.2%), MDX (9.8%), HTML (0.5%), JavaScript (0.4%), CSS (0.1%). License: MIT. Homepage: https://zod.dev Topics: runtime-validation, schema-validation, static-types, type-inference, typescript. Latest release: v4.6.5 (2w ago). Open PRs: 19, open issues: 59. Last activity: 5d ago. Community health: 85%. Top contributors: colinhacks, JacobWeisenburger, scotttrinh, pullfrog[bot], jeremyBanks, samchungy, igalklebanov, tmcw, noritaka1166, alexxander and others.