colinhacks/zod · error · Error

Unrecognized hash format

Error message

Unrecognized hash format: ${format}

What it means

Thrown by the mini `hash()` factory when the computed format string `${alg}_${enc}` has no matching regex in core.regexes. Only the cross-product of supported algorithms (md5, sha1, sha256, sha384, sha512) and encodings (hex, base64, base64url) is pre-registered (15 combos). A typo in either argument, or a casing/whitespace mismatch, yields an unrecognized format.

Solutions

  1. Use one of the supported algorithms: md5, sha1, sha256, sha384, sha512.
  2. Use one of the supported encodings: hex (default), base64, base64url — match the lowercase spelling exactly.
  3. For an unsupported algorithm, register a custom string format with `z.stringFormat('sha224_hex', /your-regex/)` instead of the `hash()` helper.

Example fix

// before
z.hash('SHA256', { enc: 'hexadecimal' }); // throws: Unrecognized hash format: SHA256_hexadecimal

// after
z.hash('sha256', { enc: 'hex' });
// or, for an unsupported algorithm, register a custom format:
const sha224Hex = z.stringFormat('sha224_hex', /^[0-9a-fA-F]{56}$/);
Defensive patterns

Strategy: validation

Validate before calling

const HASH_ALGS = ['md5', 'sha1', 'sha256', 'sha384', 'sha512'] as const;
const HASH_ENCODINGS = ['hex', 'base64', 'base64url'] as const;
type HashAlg = (typeof HASH_ALGS)[number];
type HashEnc = (typeof HASH_ENCODINGS)[number];
function assertHashFormat(alg: string, enc: string = 'hex'): void {
  if (!(HASH_ALGS as readonly string[]).includes(alg)) {
    throw new TypeError(`Unsupported hash algorithm: ${alg}. Supported: ${HASH_ALGS.join(', ')}`);
  }
  if (!(HASH_ENCODINGS as readonly string[]).includes(enc)) {
    throw new TypeError(`Unsupported hash encoding: ${enc}. Supported: ${HASH_ENCODINGS.join(', ')}`);
  }
}
// assertHashFormat(userAlg, userEnc); z.hash(userAlg as HashAlg, { enc: userEnc as HashEnc });

Type guard

function isSupportedHashFormat(alg: unknown, enc: unknown = 'hex'): boolean {
  const a = ['md5', 'sha1', 'sha256', 'sha384', 'sha512'];
  const e = ['hex', 'base64', 'base64url'];
  return typeof alg === 'string' && typeof enc === 'string' && a.includes(alg) && e.includes(enc);
}

Prevention

When it happens

Trigger: Calling `z.hash('sha256', { enc: 'hexadecimal' })` (wrong encoding name), `z.hash('SHA256')` (wrong casing), `z.hash('sha224')` (unsupported algorithm), or `z.hash('sha256', { enc: 'ascii' })`. The format string is built and looked up in the regex table; a miss throws.

Common situations: Using an algorithm Zod does not pre-register (sha224, sha3-*, blake2, ripemd); misspelling the encoding; passing uppercase from a config constant; assuming a wider algorithm set than is supported.

Related errors


AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11). Data as JSON: /api/errors/75f46f7c36be1650. Report an issue: GitHub.

Appendix: source

Thrown at packages/zod/src/v4/mini/schemas.ts:535

}

// @__NO_SIDE_EFFECTS__
export function hex(_params?: string | core.$ZodStringFormatParams): ZodMiniCustomStringFormat<"hex"> {
  return core._stringFormat(ZodMiniCustomStringFormat, "hex", core.regexes.hex, _params) as any;
}

// @__NO_SIDE_EFFECTS__
export function hash<Alg extends util.HashAlgorithm, Enc extends util.HashEncoding = "hex">(
  alg: Alg,
  params?: {
    enc?: Enc;
  } & core.$ZodStringFormatParams
): ZodMiniCustomStringFormat<`${Alg}_${Enc}`> {
  const enc = params?.enc ?? "hex";
  const format = `${alg}_${enc}` as const;
  const regex = core.regexes[format as keyof typeof core.regexes] as RegExp;
  // check for unrecognized format
  if (!regex) throw new Error(`Unrecognized hash format: ${format}`);
  return core._stringFormat(ZodMiniCustomStringFormat, format, regex, params) as any;
}

// ZodMiniNumber
interface _ZodMiniNumber<T extends core.$ZodNumberInternals<unknown> = core.$ZodNumberInternals<unknown>>
  extends _ZodMiniType<T>,
    core.$ZodNumber<T["input"]> {
  _zod: T;
}
export interface ZodMiniNumber<Input = unknown>
  extends _ZodMiniNumber<core.$ZodNumberInternals<Input>>,
    core.$ZodNumber<Input> {}
export const ZodMiniNumber: core.$constructor<ZodMiniNumber> = /*@__PURE__*/ core.$constructor(
  "ZodMiniNumber",
  (inst, def) => {
    core.$ZodNumber.init(inst, def);
    ZodMiniType.init(inst, def);
  }

View on GitHub (pinned to 2d90846af9)