-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Description
Summary
When converting a Zod tuple with rest elements to JSON Schema using draft-7
target, the generated schema incorrectly overwrites the fixed tuple items, causing all elements to be treated as rest elements. This seems to only happen when a meta({id: "abc")
id value is used.
Environment
- Zod version: v4.1.1
- Target:
draft-7
- Schema type: Tuple with rest elements
Reproduction
import z from "zod"
const primarySchema = z
.string()
.meta({ id: "primary", description: "primary thing" })
const restSchema = z.number().meta({ id: "rest", description: "rest things" })
const testSchema = z.tuple([primarySchema], restSchema)
console.log("Draft 2020-12:", JSON.stringify(
z.toJSONSchema(testSchema, { target: "draft-2020-12" }), null, 2
))
console.log("Draft 7:", JSON.stringify(
z.toJSONSchema(testSchema, { target: "draft-7" }), null, 2
))
Expected vs Actual Output
Draft 2020-12 (✅ Works Correctly)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "array",
"prefixItems": [
{ "$ref": "#/$defs/primary" }
],
"items": {
"$ref": "#/$defs/rest"
},
"$defs": {
"primary": {
"id": "primary",
"description": "primary thing",
"type": "string"
},
"rest": {
"id": "rest",
"description": "rest things",
"type": "number"
}
}
}
Draft 7 (❌ Broken)
Expected:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": [
{ "$ref": "#/definitions/primary" }
],
"additionalItems": {
"$ref": "#/definitions/rest"
},
"definitions": {
"primary": {
"id": "primary",
"description": "primary thing",
"type": "string"
},
"rest": {
"id": "rest",
"description": "rest things",
"type": "number"
}
}
}
Actual:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": { // ❌ WRONG: Should be an array of schemas
"$ref": "#/definitions/rest" // ❌ WRONG: Should reference "primary"
},
"additionalItems": {
"$ref": "#/definitions/rest"
},
"definitions": {
"primary": { // ❌ PRIMARY SCHEMA IS IGNORED
"id": "primary",
"description": "primary thing",
"type": "string"
},
"rest": {
"id": "rest",
"description": "rest things",
"type": "number"
}
}
}
Metadata
Metadata
Assignees
Labels
No labels