You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Invalid discriminator errors in Zod 4 do not list possible options like Zod 3 #5670
In Zod 3, if you received an error for an invalid discriminator, you received a list of possible options. In Zod 4, it just gives you a invalid_union code with no sub-errors or list of possible values. If the error map had access to the actual schema, it could theoretically use the discriminator to loop through the options, but this seems impossible at this point.
This is a pretty limiting regression in Zod 4, since without this information we can't tell users what they should be doing.
A dedicated invalid_union_discriminator error code
An options field listing valid discriminator values
A descriptive error message
Zod 4 consolidates this into the generic invalid_union code but loses the options information. The discriminator map (disc.value in packages/zod/src/v4/core/schemas.ts:2297-2312) already contains all valid discriminator values—they're just not being included in the error.
Suggested Fix
In packages/zod/src/v4/core/schemas.ts at line ~2337, add an options field:
payload.issues.push({code: "invalid_union",errors: [],note: "No matching discriminator",discriminator: def.discriminator,options: Array.from(disc.value.keys()),// ← Add this
input,path: [def.discriminator],
inst,});
Then update packages/zod/src/v4/locales/en.ts to produce a better message when options is present on invalid_union issues.
This would restore the Zod 3 behavior while keeping the unified invalid_union error code.
Activity
pullfrog commentedon Jan 28, 2026
Issue Reproduction Confirmed ✅
I reproduced the issue and verified the difference between Zod 3 and Zod 4:
Zod 4 output:
[ { "code": "invalid_union", "errors": [], "note": "No matching discriminator", "discriminator": "type", "path": ["type"], "message": "Invalid input" } ]Zod 3 output:
[ { "code": "invalid_union_discriminator", "options": ["fruit", "vegetable"], "path": ["type"], "message": "Invalid discriminator value. Expected 'fruit' | 'vegetable'" } ]Analysis
This is a valid regression. Zod 3 provided:
invalid_union_discriminatorerror codeoptionsfield listing valid discriminator valuesZod 4 consolidates this into the generic
invalid_unioncode but loses theoptionsinformation. The discriminator map (disc.valueinpackages/zod/src/v4/core/schemas.ts:2297-2312) already contains all valid discriminator values—they're just not being included in the error.Suggested Fix
In
packages/zod/src/v4/core/schemas.tsat line ~2337, add anoptionsfield:Then update
packages/zod/src/v4/locales/en.tsto produce a better message whenoptionsis present oninvalid_unionissues.This would restore the Zod 3 behavior while keeping the unified
invalid_unionerror code.BrendanC23 commentedon Jan 29, 2026
See #5086 for a related discussion.
Danielchinasa commentedon Feb 18, 2026
I'd like to work on this issue. Can you assign it to me?
fix: add options to invalid discriminator errors
fix: add options to invalid discriminator errors (colinhacks#5723)