{"id":"d14797bee0f9e7a2","repo":"colinhacks/zod","slug":"duplicate-discriminator-value-string-v","errorCode":null,"errorMessage":"Duplicate discriminator value \"${String(v)}\"","messagePattern":"Duplicate discriminator value \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/schemas.ts","lineNumber":2393,"sourceCode":"          if (!propValues[k]) propValues[k] = new Set();\n          for (const val of v) {\n            propValues[k].add(val);\n          }\n        }\n      }\n      return propValues;\n    });\n\n    const disc = util.cached(() => {\n      const opts = def.options as $ZodTypeDiscriminable[];\n      const map: Map<util.Primitive, $ZodType> = new Map();\n      for (const o of opts) {\n        const values = o._zod.propValues?.[def.discriminator];\n        if (!values || values.size === 0)\n          throw new Error(`Invalid discriminated union option at index \"${def.options.indexOf(o)}\"`);\n        for (const v of values) {\n          if (map.has(v)) {\n            throw new Error(`Duplicate discriminator value \"${String(v)}\"`);\n          }\n          map.set(v, o);\n        }\n      }\n      return map;\n    });\n\n    inst._zod.parse = (payload, ctx) => {\n      const input = payload.value;\n      if (!util.isObject(input)) {\n        payload.issues.push({\n          code: \"invalid_type\",\n\n          expected: \"object\",\n          input,\n          inst,\n        });\n        return payload;","sourceCodeStart":2375,"sourceCodeEnd":2411,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/schemas.ts#L2375-L2411","documentation":"Thrown while building the discriminator map in `$ZodDiscriminatedUnion`. Two different options register the same discrete value for the discriminator key, so the parser could not decide which option to select. Discriminated unions require each option's discriminator value(s) to be unique across the union.","triggerScenarios":"Two options both declaring `type: z.literal('user')`, or two enum-backed discriminator fields whose allowed values overlap (e.g. one `z.enum(['a','b'])` and another `z.enum(['b','c'])` where the shared value is 'b').","commonSituations":"Adding a new variant and accidentally reusing an existing discriminator value; using unions of literals for the discriminator that overlap between options; merging two separately-defined unions that happen to share a value.","solutions":["Look at the duplicate value in the message and find which two options both permit it; change one of them to a distinct literal/enum value.","If overlap is intentional, discriminated union is the wrong tool — use `z.union([...])` and disambiguate with `.refine()` instead.","Audit each option's discriminator field (especially enum/unions of literals) to ensure the sets are disjoint."],"exampleFix":"// before\nconst U = z.discriminatedUnion('type', [\n  z.object({ type: z.literal('admin'), perms: z.array(z.string()) }),\n  z.object({ type: z.literal('admin'), scope: z.string() }), // duplicate 'admin'\n]);\n\n// after\nconst U = z.discriminatedUnion('type', [\n  z.object({ type: z.literal('admin'), perms: z.array(z.string()) }),\n  z.object({ type: z.literal('superadmin'), scope: z.string() }),\n]);","handlingStrategy":"validation","validationCode":"function assertUniqueDiscriminatorValues(discriminator, options) {\n  const seen = new Map();\n  options.forEach((opt, i) => {\n    const vals = opt._zod?.propValues?.[discriminator] ?? new Set();\n    for (const v of vals) {\n      if (seen.has(v)) throw new Error(`Duplicate discriminator \"${String(v)}\" at options ${seen.get(v)} and ${i}`);\n      seen.set(v, i);\n    }\n  });\n}","typeGuard":null,"tryCatchPattern":"try {\n  const U = z.discriminatedUnion('type', options);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Duplicate discriminator value')) {\n    // parse out the value, locate the two colliding options, make them distinct\n  }\n  throw e;\n}","preventionTips":["Give each variant a distinct, descriptive discriminator literal.","When using z.enum/z.literal unions as the discriminator, verify the value sets are disjoint.","Lint for repeated literal values across variant definitions in the same union."],"tags":["discriminated-union","schema-definition","validation"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}