can1357/oh-my-pi · error · OmpTypeError
multipleOf must be greater than zero
Error message
multipleOf must be greater than zero
What it means
Beyond finiteness, `tNumber` requires `multipleOf` to be strictly greater than zero. A zero or negative multipleOf is mathematically meaningless for the constraint (every value is a multiple of... nothing) and is rejected at schema construction with this message.
Source
Thrown at packages/omptype/src/typebox.ts:262
case "uuid":
return value => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
case "date-time":
return value =>
/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d)$/.test(value) &&
!Number.isNaN(Date.parse(value));
case "date":
return value => /^\d{4}-\d\d-\d\d$/.test(value) && !Number.isNaN(Date.parse(`${value}T00:00:00Z`));
default:
return () => true;
}
}
function tNumber(opts?: NumberOpts, integer = false): TNumber {
for (const key of ["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf"] as const) {
checkFiniteOption(key, opts?.[key]);
}
if (opts?.multipleOf !== undefined && opts.multipleOf <= 0)
throw new OmpTypeError("multipleOf must be greater than zero");
let lower: { value: number; exclusive: boolean } | undefined;
if (opts?.minimum !== undefined) lower = { value: opts.minimum, exclusive: false };
if (opts?.exclusiveMinimum !== undefined && (!lower || opts.exclusiveMinimum >= lower.value)) {
lower = { value: opts.exclusiveMinimum, exclusive: true };
}
let upper: { value: number; exclusive: boolean } | undefined;
if (opts?.maximum !== undefined) upper = { value: opts.maximum, exclusive: false };
if (opts?.exclusiveMaximum !== undefined && (!upper || opts.exclusiveMaximum <= upper.value)) {
upper = { value: opts.exclusiveMaximum, exclusive: true };
}
const keyword = integer ? "number.integer" : "number";
// The `LO <= TYPE <= HI` range spelling requires both bounds; a min-only
// bound must use the postfix `TYPE >= LO` form (see parseBounded in ir.ts).
let src: string;
if (lower && upper) {
src = `${lower.value} ${lower.exclusive ? "<" : "<="} ${keyword} ${upper.exclusive ? "<" : "<="} ${upper.value}`;
} else if (lower) {
src = `${keyword} ${lower.exclusive ? ">" : ">="} ${lower.value}`;View on GitHub (pinned to 9690622007)
Solutions
- Ensure the value passed is > 0; validate with `step > 0` before constructing the schema.
- If no step constraint is desired, omit `multipleOf` instead of passing 0.
- Use `Math.abs()` only if a negative step is acceptable as a magnitude — then pass the absolute value.
Example fix
// before
tNumber({ multipleOf: options.step }); // step may be 0
// after
const step = options.step > 0 ? options.step : undefined;
tNumber(step !== undefined ? { multipleOf: step } : undefined); Defensive patterns
Strategy: validation
Validate before calling
function positiveMultipleOf(n: number | undefined): number | undefined {
if (n === undefined) return undefined;
if (!(typeof n === 'number' && Number.isFinite(n) && n > 0)) throw new RangeError(`multipleOf must be > 0, got ${n}`);
return n;
} Type guard
function isValidMultipleOf(v: unknown): v is number {
return typeof v === "number" && Number.isFinite(v) && v > 0;
} Try / catch
try {
const schema = tNumber({ multipleOf: step });
} catch (err) {
if (err instanceof Error && err.message === 'multipleOf must be greater than zero') {
throw new Error(`Configured step must be a positive number, got ${step}`);
}
throw err;
} Prevention
- Validate step/multipleOf inputs at the config boundary (`step > 0`).
- Omit multipleOf entirely when no step constraint is intended.
- Watch derived values that can hit 0 (empty defaults, division results).
When it happens
Trigger: `tNumber({ multipleOf: 0 })`, `tNumber({ multipleOf: -2 })`, or `multipleOf` computed from a variable that ends up 0/negative (e.g. step derived from config defaulting to 0).
Common situations: Building dynamic numeric schemas where the step comes from user config or a UI input that can be 0; sign errors when deriving step from a direction-aware value.
Related errors
- ${name} must be finite
- invalid regular expression pattern ${JSON.stringify(opts.pat
- Type.${operation} requires a schema created by Type.Object
- ${kind} length must be a nonnegative safe integer
- object mode requires an object schema
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b33aef9564e62f68.
Report an issue: GitHub.