can1357/oh-my-pi · error · OmpTypeError
divisor must be non-zero
Error message
divisor must be non-zero
What it means
`divisibleBy` validates its divisor before installing it on the number IR. A divisor that is not a finite number or is exactly 0 makes the constraint unsatisfiable or meaningless, so omptype throws 'divisor must be non-zero' as an OmpTypeError.
Source
Thrown at packages/omptype/src/type.ts:836
atLeast(this: InternalType, bound: number): InternalType {
return makeType(withNumericBound(this.ir, "min", bound), this[kSteps], metaOf(this));
},
atMost(this: InternalType, bound: number): InternalType {
return makeType(withNumericBound(this.ir, "max", bound), this[kSteps], metaOf(this));
},
moreThan(this: InternalType, bound: number): InternalType {
return makeType(withNumericBound(this.ir, "min", bound, true), this[kSteps], metaOf(this));
},
lessThan(this: InternalType, bound: number): InternalType {
return makeType(withNumericBound(this.ir, "max", bound, true), this[kSteps], metaOf(this));
},
divisibleBy(this: InternalType, divisor: number): InternalType {
if (this.ir.k !== "number") throw new OmpTypeError(`cannot apply divisibility to ${this.ir.k}`);
if (!Number.isFinite(divisor) || divisor === 0) throw new OmpTypeError("divisor must be non-zero");
return makeType({ ...this.ir, divisor }, this[kSteps], metaOf(this));
},
positive(this: InternalType): InternalType {
return makeType(withNumericBound(this.ir, "min", 0, true), this[kSteps], metaOf(this));
},
negative(this: InternalType): InternalType {
return makeType(withNumericBound(this.ir, "max", 0, true), this[kSteps], metaOf(this));
},
nonNegative(this: InternalType): InternalType {
return makeType(withNumericBound(this.ir, "min", 0), this[kSteps], metaOf(this));
},
nonPositive(this: InternalType): InternalType {
return makeType(withNumericBound(this.ir, "max", 0), this[kSteps], metaOf(this));
},View on GitHub (pinned to 9690622007)
Solutions
- Pass a non-zero finite number: `type('number').divisibleBy(5)`.
- Validate the divisor before calling: `Number.isFinite(d) && d !== 0`.
- Fix the upstream computation producing 0/Infinity/NaN.
Example fix
// before
const d = getConfig().step; // may be 0
const T = type('number').divisibleBy(d); // throws when d === 0
// after
if (Number.isFinite(d) && d !== 0) {
const T = type('number').divisibleBy(d);
} Defensive patterns
Strategy: validation
Validate before calling
function validDivisor(d) {
return Number.isFinite(d) && d !== 0;
}
if (!validDivisor(config.step)) throw new Error('config.step must be non-zero finite');
const T = type('number').divisibleBy(config.step); Type guard
function isUsableDivisor(d) {
return typeof d === 'number' && Number.isFinite(d) && d !== 0;
} Try / catch
try {
const T = type('number').divisibleBy(d);
} catch (e) {
if (e instanceof OmpTypeError && e.message.includes('divisor must be non-zero')) {
// substitute a safe default divisor
} else throw e;
} Prevention
- Validate config/env-sourced divisors at startup, before schema construction.
- Guard upstream arithmetic that can yield 0, Infinity, or NaN.
- Centralize divisor validation in one helper used by all schema builders.
When it happens
Trigger: `type('number').divisibleBy(0)`, `.divisibleBy(Infinity)`, `.divisibleBy(NaN)`, or passing a divisor computed at runtime that can evaluate to 0 (e.g. from config or division by zero upstream).
Common situations: Divisor read from config/env defaulting to 0; arithmetic producing Infinity/NaN (x/0) passed straight into `.divisibleBy`.
Related errors
- cannot apply divisibility to ${this.ir.k}
- Invalid pattern: {err}
- unknown file type: {value}
- invalid size: {value}
- 2
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1e355005e6fae728.
Report an issue: GitHub.