Skip to content

z.xor() works fine with strict objects but breaks with regular ones #6342

Description

@RareScrap

For some reason the code below fails in a really weird way. With the given input both gentleXor and strictXor must successfully parse the input but gentleXor fails.

import z from "zod"

const input = {
    "os": {
        "name": "windows",
        "version": "^10\\."
    }
}

const nameOsRule = z.object({
    name: z.enum(["windows", "osx", "linux"]).nonoptional()
})

const versionOsRule = nameOsRule.extend({
    version: z.string().nonempty().nonoptional()
})

// This will break
const gentleXor = z.xor([
    nameOsRule,
    versionOsRule
])

// The strict version works fine
const strictXor = z.xor([
    z.strictObject(nameOsRule.shape),
    z.strictObject(versionOsRule.shape)
])

gentleXor.parse(input.os, { reportInput: true })
strictXor.parse(input.os, { reportInput: true })

The error doesn't give any clue and looks uninformative:

ZodError: [
  {
    "code": "invalid_union",
    "errors": [],
    "inclusive": false,
    "path": [],
    "message": "Invalid input",
    "input": {
      "name": "windows",
      "version": "^10\\."
    }
  }
]

Can someone explain me why this breaks?

Zod version is 4.4.3

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