What the docs say
JSONSchemaGeneratorParams.unrepresentable, packages/zod/src/v4/core/to-json-schema.ts:52:
* - `"any"` — Unrepresentable types become `{}`
A bigint literal is unrepresentable: with the default unrepresentable: "throw", toJSONSchema throws BigInt literals cannot be represented in JSON Schema (json-schema-processors.ts:311).
Reproduction (main at 10dda3a)
import * as z from "zod";
z.toJSONSchema(z.literal(9007199254740993n), { unrepresentable: "any" });
// => { $schema: "...", type: "number", const: 9007199254740992 }
Expected {} (plus $schema). Instead the value is silently rounded to the nearest double, so the emitted schema rejects the literal's own value and accepts a different one, with no warning.
Cause
In literalProcessor, after handleUnrepresentable returns false for "any", the member still reaches vals.push(Number(val)) (json-schema-processors.ts:313).
Proposed fix
Drop a bigint member that does not survive a Number() round-trip, the same way an undefined member is already dropped a few lines above (+4 −2 in literalProcessor). Safe-integer bigint literals keep today's behaviour, so the existing snapshot z.literal([undefined, 1n, "a"]) → enum: [1, "a"] still holds. The "any" bullet in the JSDoc would then state the bigint exception precisely.
A branch with the fix, a test that quotes the JSDoc sentence, and the JSDoc wording (4 commits, 3 files, +20 −2; the fork's test and lint jobs pass):
main...kazikimaguro13:zod:vf/e1-014-pr
Opening a pull request is limited to collaborators on this repository, and CONTRIBUTING asks for an issue first, so I'm filing this instead. Happy for it to be cherry-picked or reworked, or to open a PR if you'd like that route.
The finding, test and fix were produced with AI assistance and checked with an experimental tool (verified-fix): the test was derived from the JSDoc sentence, and the fix passed mutation testing on the changed lines (3/3 killed), a type check with no new errors, and the full suite unchanged.
What the docs say
JSONSchemaGeneratorParams.unrepresentable,packages/zod/src/v4/core/to-json-schema.ts:52:A bigint literal is unrepresentable: with the default
unrepresentable: "throw",toJSONSchemathrowsBigInt literals cannot be represented in JSON Schema(json-schema-processors.ts:311).Reproduction (
mainat10dda3a)Expected
{}(plus$schema). Instead the value is silently rounded to the nearest double, so the emitted schema rejects the literal's own value and accepts a different one, with no warning.Cause
In
literalProcessor, afterhandleUnrepresentablereturnsfalsefor"any", the member still reachesvals.push(Number(val))(json-schema-processors.ts:313).Proposed fix
Drop a bigint member that does not survive a
Number()round-trip, the same way anundefinedmember is already dropped a few lines above (+4 −2 inliteralProcessor). Safe-integer bigint literals keep today's behaviour, so the existing snapshotz.literal([undefined, 1n, "a"])→enum: [1, "a"]still holds. The"any"bullet in the JSDoc would then state the bigint exception precisely.A branch with the fix, a test that quotes the JSDoc sentence, and the JSDoc wording (4 commits, 3 files, +20 −2; the fork's test and lint jobs pass):
main...kazikimaguro13:zod:vf/e1-014-pr
Opening a pull request is limited to collaborators on this repository, and CONTRIBUTING asks for an issue first, so I'm filing this instead. Happy for it to be cherry-picked or reworked, or to open a PR if you'd like that route.
The finding, test and fix were produced with AI assistance and checked with an experimental tool (verified-fix): the test was derived from the JSDoc sentence, and the fix passed mutation testing on the changed lines (3/3 killed), a type check with no new errors, and the full suite unchanged.