Incomplete ZodError with recursive types and regexps?
See original GitHub issueI believe I am seeing unexpected ZodError behavior with recursive types that use regexps. It’s also entirely possible I am misunderstanding as the error handling is fairly complex – but at least I cannot explain how the version with the regexp cannot find the path to the error, and without the regexp can.
const dogSchema = z.object({
type: z.literal('dog'),
dogname: z.string()
});
const catSchema = z.object({
type: z.literal('cat'),
catname: z.string()
});
const birdSchema = z.object({
type: z.string().regex(/bird/), <------ Uses a regexp
birdname: z.string()
});
const categorySchema = z.object({
type: z.literal('category'),
category: z.string(),
animal: z.lazy(() => animalSchema)
})
const animalSchema = z.union([
dogSchema,
catSchema,
birdSchema,
categorySchema,
])
const masterSchema = z.object({
animals: animalSchema,
})
const input = {
animals: {
type: 'category',
category: 'pets',
animal: {
type: 'cat',
// Missing catname. <------ No catname! Input error.
}
}
}
const parseResult = masterSchema.safeParse(input);
if (!parseResult.success) {
console.info(parseResult.error);
}
On running this, I receive the following. Zod cannot discriminate the unions (which is WAI), but it also seemingly cannot pin down where the error is. Notice no reference to catname
below (in the nested context):
ZodError: [
{
"code": "invalid_union",
"unionErrors": [
{
"issues": [
{
"code": "invalid_type",
"expected": "dog",
"received": "category",
"path": [
"animals",
"type"
],
"message": "Expected dog, received category"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"dogname"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "cat",
"received": "category",
"path": [
"animals",
"type"
],
"message": "Expected cat, received category"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"catname" <--- (not the nested catname)
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"validation": "regex",
"code": "invalid_string",
"message": "Invalid",
"path": [
"animals",
"type"
]
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"birdname"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"validation": "regex",
"code": "invalid_string",
"message": "Invalid",
"path": [
"animals",
"animal",
"type"
]
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"animal",
"birdname"
],
"message": "Required"
}
],
"name": "ZodError"
}
],
"path": [
"animals"
],
"message": "Invalid input"
}
]
If I change:
type: z.string().regex(/bird/)
to type: z.literal('bird')
I get:
ZodError: [
{
"code": "invalid_union",
"unionErrors": [
{
"issues": [
{
"code": "invalid_type",
"expected": "dog",
"received": "cat",
"path": [
"animals",
"animal",
"type"
],
"message": "Expected dog, received cat"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"animal",
"dogname"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"animal",
"catname" <----------------------------------------------------- THIS IS WHAT I EXPECT
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "bird",
"received": "cat",
"path": [
"animals",
"animal",
"type"
],
"message": "Expected bird, received cat"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"animal",
"birdname"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "category",
"received": "cat",
"path": [
"animals",
"animal",
"type"
],
"message": "Expected category, received cat"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"animals",
"animal",
"category"
],
"message": "Required"
},
{
"code": "invalid_union",
"unionErrors": [
{
"issues": [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"animals",
"animal",
"animal"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"animals",
"animal",
"animal"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"animals",
"animal",
"animal"
],
"message": "Required"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"animals",
"animal",
"animal"
],
"message": "Required"
}
],
"name": "ZodError"
}
],
"path": [
"animals",
"animal",
"animal"
],
"message": "Invalid input"
}
],
"name": "ZodError"
}
],
"path": [
"animals",
"animal"
],
"message": "Invalid input"
}
]
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (8 by maintainers)
Top Results From Across the Web
Error when using recursive type in a function - Stack Overflow
I have a recursive type that extracts the indices from a nested object and puts them in a flat, strongly-typed tuple, like so:...
Read more >Recursive Regex—Tutorial - RexEgg
About Recursive Regular Expressions. Advanced Regex Tutorial with examples and full tracing of the engine matches.
Read more >bleachbit Scrollbar broken on release 4.4 - Python - GitAnswer
Node & edges connection types are nullable - graphql-relay-js · How to implement Pan ? ... zod Incomplete ZodError with recursive types and...
Read more >A Recursive Variant Library for C++ : r/cpp - Reddit
Instantiating standard library templates with an incomplete type is an error, NDR unless explicitly exempted. std::variant provides no such ...
Read more >Parsing regular expressions with recursive descent - Matt Might
At a high level, the structure of the parser is: /* A data type to represent a regular expression. */ abstract class RegEx...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Perfect, the correct error is included as I expected in my original usecase and I am able to surface it as the likely ‘cause’ as a result.
Thanks @colinhacks, both for this fix and for Zod overall (the solution to my search for "Surely – surely – an intuitive tool that does ${zod} must exist … ").
Merged in zod@3.11.0