colinhacks/zod · error · Error

Invalid UUID version: "${def.version}"

Error message

Invalid UUID version: "${def.version}"

What it means

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.

Source

Thrown at packages/zod/src/v4/core/schemas.ts:443

export interface $ZodUUID extends $ZodType {
  _zod: $ZodUUIDInternals;
}

export const $ZodUUID: core.$constructor<$ZodUUID> = /*@__PURE__*/ core.$constructor("$ZodUUID", (inst, def): void => {
  if (def.version) {
    const versionMap: Record<string, number> = {
      v1: 1,
      v2: 2,
      v3: 3,
      v4: 4,
      v5: 5,
      v6: 6,
      v7: 7,
      v8: 8,
    };
    const v = versionMap[def.version];
    if (v === undefined) throw new Error(`Invalid UUID version: "${def.version}"`);
    def.pattern ??= regexes.uuid(v);
  } else def.pattern ??= regexes.uuid();
  $ZodStringFormat.init(inst, def);
});

//////////////////////////////   ZodEmail   //////////////////////////////

export interface $ZodEmailDef extends $ZodStringFormatDef<"email"> {}
export interface $ZodEmailInternals extends $ZodStringFormatInternals<"email"> {}
export interface $ZodEmail extends $ZodType {
  _zod: $ZodEmailInternals;
}

export const $ZodEmail: core.$constructor<$ZodEmail> = /*@__PURE__*/ core.$constructor(
  "$ZodEmail",
  (inst, def): void => {
    def.pattern ??= regexes.email;
    $ZodStringFormat.init(inst, def);

View on GitHub (pinned to 912f0f51b0)

Solutions

  1. Use a lowercase `"v" + n` string in the range v1-v8, e.g. `z.uuid({ version: "v4" })`.
  2. If the version comes from dynamic input, constrain/validate it: `as const` union or a guard against the allowed set.
  3. Omit `version` entirely to accept any UUID (`z.uuid()`).

Example fix

// before
const s = z.uuid({ version: "v9" }); // throws
// after
const s = z.uuid({ version: "v4" });
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = ["v1","v2","v3","v4","v5","v6","v7","v8"] as const;
type UuidVersion = (typeof ALLOWED)[number];
function uuid(version?: UuidVersion) {
  if (version && !ALLOWED.includes(version as UuidVersion)) {
    throw new Error(`Invalid UUID version: "${version}". Allowed: ${ALLOWED.join(", ")}`);
  }
  return z.uuid(version ? { version } : undefined);
}

Type guard

const UUID_VERSIONS = new Set(["v1","v2","v3","v4","v5","v6","v7","v8"]);
function isUuidVersion(v: unknown): v is `v${1|2|3|4|5|6|7|8}` {
  return typeof v === "string" && UUID_VERSIONS.has(v);
}

Prevention

When it happens

Trigger: 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"`.

Common situations: 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.

Related errors


AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03). Data as JSON: /data/errors/1aad5c6e861a4dc3.json. Report an issue: GitHub.