Validate object field as a single value with Zod
I'm building a form to create an organization in my project. The form includes an address field, which is an object, as shown in the attached schema.
The issue I'm facing is with how validation errors are handled. When I submit the form, the errors returned by
props.formApi.getAllErrors()
put all the address-related errors into form.errors
, instead of nesting them under fields.address
.
Currently, the only way I can validate the address field as an object is by attaching the validator directly to the field itself. However, this approach causes only the address field to be validated on submit (if there is an error on this field), not the entire form.
Is there a way, either with Zod or TanStack Form, to validate an object field (like address) directly as a single value — meaning, treating the field as a whole object — instead of validating it through individual nested keys?
I'm looking for something like a mode="value" to treat the object as the field's value, and maybe something like mode="object" to allow deep key error handling — similar to how mode="array" works for arrays.
11 Replies
deep-jade•2mo ago
are you sure that's the issue? what may be happening is that the fields are mapped too specifically
where the
address
field is not marked as error, but address.streetNumber
yes, form.errors
will have a copy of the error, but the mapped fields are probably listed in it. Can you share the JSON.stringify
version of the form error?
Zod v3 -> v4 changed how some paths work, so it can help figure out the problem
I have to say, I really like the idea of mode="object"
to mark a field as a compound field! I'm tempted to bring that up to other maintainerssunny-greenOP•2mo ago
Here is the only field I have with address in the name. And the JSON of the error
sunny-greenOP•2mo ago
A mode object could be cool yes to validate the field as one and not as deep keys for some fields
deep-jade•2mo ago
It looks like zod v4's documentation is a bit lacking. This isn't as pretty as I'd like it to be, but it should be worth a try
this one doesn't even check if the issue originates from
address
, for examplesunny-greenOP•2mo ago
This should work yes I think. But I don't know why .check is never trigger. I added a log in check and there is nothing. I tried even with .safeParse and nothing trigger .check
deep-jade•2mo ago
zod has a concept of fatal errors vs. non-fatal. For example, if something is undefined when you expect string, it will not perform a
min(1)
check. Maybe that's why it's not triggered?
maybe in this case it's easier to parse first and then edit the return value :Hmm:
sunny-greenOP•2mo ago
Ok it was the problem for check, my default value was:
But there it's weird that when lat and lng are NaN there is no error with z.number() but with 1 it works so I tried with changing the path but it's not working. When I changed the pass in the end the path is ['address', 'address'].
Is it possible to force fatal errors everywhere ? There is nothing about fatal vs. non-fatal error on zod documentation right ? I can't find it
deep-jade•2mo ago
I mostly saw fatal vs. non-fatal when making your own refinements (
superRefine
). This probably also applies to check
deep-jade•2mo ago
deep-jade•2mo ago

sunny-greenOP•2mo ago
Ok I found a way. So first I setup a defaultValue that is valid in term of primitive (So no NaN for a number).
Then in the check function I modify all issues with a path of []. Which then convert in the pass of the object. And it seems to work well now.
Didn't know about this fatal and non-fatal error on zod. Good to know. Maybe could be good to override the continue on the invalid_type of zod primitive or change how the object of zod work but I can't think of a good solution for that to get errors on the parent type