{"id":"1aad5c6e861a4dc3","repo":"colinhacks/zod","slug":"invalid-uuid-version-def-version","errorCode":null,"errorMessage":"Invalid UUID version: \"${def.version}\"","messagePattern":"Invalid UUID version: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/schemas.ts","lineNumber":443,"sourceCode":"\nexport interface $ZodUUID extends $ZodType {\n  _zod: $ZodUUIDInternals;\n}\n\nexport const $ZodUUID: core.$constructor<$ZodUUID> = /*@__PURE__*/ core.$constructor(\"$ZodUUID\", (inst, def): void => {\n  if (def.version) {\n    const versionMap: Record<string, number> = {\n      v1: 1,\n      v2: 2,\n      v3: 3,\n      v4: 4,\n      v5: 5,\n      v6: 6,\n      v7: 7,\n      v8: 8,\n    };\n    const v = versionMap[def.version];\n    if (v === undefined) throw new Error(`Invalid UUID version: \"${def.version}\"`);\n    def.pattern ??= regexes.uuid(v);\n  } else def.pattern ??= regexes.uuid();\n  $ZodStringFormat.init(inst, def);\n});\n\n//////////////////////////////   ZodEmail   //////////////////////////////\n\nexport interface $ZodEmailDef extends $ZodStringFormatDef<\"email\"> {}\nexport interface $ZodEmailInternals extends $ZodStringFormatInternals<\"email\"> {}\nexport interface $ZodEmail extends $ZodType {\n  _zod: $ZodEmailInternals;\n}\n\nexport const $ZodEmail: core.$constructor<$ZodEmail> = /*@__PURE__*/ core.$constructor(\n  \"$ZodEmail\",\n  (inst, def): void => {\n    def.pattern ??= regexes.email;\n    $ZodStringFormat.init(inst, def);","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/schemas.ts#L425-L461","documentation":"The `$ZodUUID` constructor (schemas.ts:430) maps the `version` option through a fixed `versionMap` of v1-v8 (schemas.ts:432). If `def.version` is set but not one of those keys, `versionMap[def.version]` is `undefined` and it throws at construction time (schemas.ts:443). This fires when the schema is built, not when it parses.","triggerScenarios":"Constructing `z.uuid({ version: \"v9\" })`, `z.uuid({ version: 4 })` (number instead of string), or any typo like `z.uuid({ version: \"V4\" })`. The version must be a string `\"v1\"`..`\"v8\"`.","commonSituations":"Passing a numeric version (`4` instead of `\"v4\"`); uppercase typo (`\"V4\"`); inventing a version not in the map; reading the version from env/config without validating it.","solutions":["Use a lowercase `\"v\" + n` string in the range v1-v8, e.g. `z.uuid({ version: \"v4\" })`.","If the version comes from dynamic input, constrain/validate it: `as const` union or a guard against the allowed set.","Omit `version` entirely to accept any UUID (`z.uuid()`)."],"exampleFix":"// before\nconst s = z.uuid({ version: \"v9\" }); // throws\n// after\nconst s = z.uuid({ version: \"v4\" });","handlingStrategy":"validation","validationCode":"const ALLOWED = [\"v1\",\"v2\",\"v3\",\"v4\",\"v5\",\"v6\",\"v7\",\"v8\"] as const;\ntype UuidVersion = (typeof ALLOWED)[number];\nfunction uuid(version?: UuidVersion) {\n  if (version && !ALLOWED.includes(version as UuidVersion)) {\n    throw new Error(`Invalid UUID version: \"${version}\". Allowed: ${ALLOWED.join(\", \")}`);\n  }\n  return z.uuid(version ? { version } : undefined);\n}","typeGuard":"const UUID_VERSIONS = new Set([\"v1\",\"v2\",\"v3\",\"v4\",\"v5\",\"v6\",\"v7\",\"v8\"]);\nfunction isUuidVersion(v: unknown): v is `v${1|2|3|4|5|6|7|8}` {\n  return typeof v === \"string\" && UUID_VERSIONS.has(v);\n}","tryCatchPattern":null,"preventionTips":["Always pass the version as a lowercase `\"vN\"` string, never a number.","Constrain dynamic versions to the v1-v8 set before constructing the schema.","Omit `version` when any UUID should be accepted."],"tags":["uuid","validation","construction-time","config"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}