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
- Use one of the supported algorithms: md5, sha1, sha256, sha384, sha512.
- Use one of the supported encodings: hex (default), base64, base64url — match the lowercase spelling exactly.
- 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
- Lowercase and trim user-supplied algorithm/encoding before passing to `z.hash()`.
- Validate alg/enc against the supported cross-product (5 algs x 3 encs) at the config boundary.
- For unsupported algorithms, register a custom format with `z.stringFormat()` instead of forcing `z.hash()`.
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
- Unrecognized hash format
- Cannot specify both `message` and `error` params
- Invalid hex string length
- Cannot create literal schema with no valid values
- Cannot overwrite keys on object schemas containing…
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)