colinhacks/zod · error · Error
Cannot mix number and bigint in multiple_of check.
Error message
Cannot mix number and bigint in multiple_of check.
What it means
The `multiple_of` check (checks.ts:168) computes divisibility differently for numbers (float-safe remainder) vs bigints (native `%`). To pick the right branch it asserts `typeof payload.value === typeof def.value` at checks.ts:177 and throws if they differ. This is a parse-time throw, not construction-time: it fires when the runtime input type does not match the divisor's type.
Source
Thrown at packages/zod/src/v4/core/checks.ts:178
def: $ZodCheckMultipleOfDef<T>;
issc: errors.$ZodIssueNotMultipleOf;
}
export interface $ZodCheckMultipleOf<T extends number | bigint = number | bigint> extends $ZodCheck<T> {
_zod: $ZodCheckMultipleOfInternals<T>;
}
export const $ZodCheckMultipleOf: core.$constructor<$ZodCheckMultipleOf<number | bigint>> =
/*@__PURE__*/ core.$constructor("$ZodCheckMultipleOf", (inst, def) => {
$ZodCheck.init(inst, def);
inst._zod.onattach.push((inst) => {
inst._zod.bag.multipleOf ??= def.value;
});
inst._zod.check = (payload) => {
if (typeof payload.value !== typeof def.value)
throw new Error("Cannot mix number and bigint in multiple_of check.");
const isMultiple =
typeof payload.value === "bigint"
? payload.value % (def.value as bigint) === BigInt(0)
: util.floatSafeRemainder(payload.value, def.value as number) === 0;
if (isMultiple) return;
payload.issues.push({
origin: typeof payload.value as "number",
code: "not_multiple_of",
divisor: def.value as number,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
/////////////////////////////////////View on GitHub (pinned to 912f0f51b0)
Solutions
- Match the divisor type to the schema: `z.bigint().multipleOf(BigInt(5))` for bigint, `z.number().multipleOf(5)` for number.
- Normalize the input to the expected type before parsing (e.g. `BigInt(x)` for bigint schemas).
- If inputs are genuinely mixed, split into two schemas and branch on `typeof` before parsing.
Example fix
// before const schema = z.bigint().multipleOf(5); // 5 is number -> throws on parse schema.parse(BigInt(10)); // after const schema = z.bigint().multipleOf(BigInt(5)); schema.parse(BigInt(10));
Defensive patterns
Strategy: validation
Validate before calling
// Ensure divisor type matches schema type before constructing.
function bigintMultipleOf(divisor: bigint) {
return z.bigint().multipleOf(divisor); // divisor MUST be bigint
}
function numberMultipleOf(divisor: number) {
return z.number().multipleOf(divisor); // divisor MUST be number
} Type guard
function isBigIntSchemaDivisor(v: unknown): v is bigint {
return typeof v === "bigint";
}
// before building: ensure typeof(schema input) === typeof(divisor) Try / catch
try {
schema.parse(input);
} catch (e) {
if (e instanceof Error && /Cannot mix number and bigint/.test(e.message)) {
// normalize input type and retry, or report a typed error
}
throw e;
} Prevention
- Always wrap bigint divisors in `BigInt()`, never pass a raw number literal.
- Keep number and bigint schemas on separate code paths; do not branch input by type into one schema.
- At JSON boundaries (no bigint), coerce to BigInt before parsing a bigint schema.
When it happens
Trigger: Defining `z.bigint().multipleOf(5)` (5 is a plain number) then `.parse(BigInt(10))`; OR `z.number().multipleOf(BigInt(5))` then `.parse(10)`. Also reachable by feeding a bigint into a number schema with a numeric divisor or vice versa via `.safeParse` on mixed data.
Common situations: Forgetting the `BigInt()` wrapper on the divisor when building a bigint schema; deserializing JSON (which has no bigint) into a bigint schema; a code path that sometimes receives a number and sometimes a bigint; refactoring a number schema to bigint without updating the divisor.
Related errors
- BigInt cannot be represented in JSON Schema
- BigInt literals cannot be represented in JSON Schema
- NaN cannot be represented in JSON Schema
- Unmergable intersection. Error path: ${JSON.stringify(merged
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/28f41809f2cc6506.json.
Report an issue: GitHub.