Skip to content

toJSONSchema({ unrepresentable: "any" }) silently rounds bigint literals outside the safe-integer range #6625

Description

@kazikimaguro13

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions