can1357/oh-my-pi · error · OmpTypeError
cannot apply divisibility to ${this.ir.k}
Error message
cannot apply divisibility to ${this.ir.k} What it means
`.divisibleBy(n)` is only defined for number types. `divisibleBy` checks `this.ir.k !== "number"` and throws an OmpTypeError naming the actual kind when called on any other type (string, object, boolean, etc.). Divisibility is a numeric-only constraint, so applying it elsewhere is a type-level misuse.
Source
Thrown at packages/omptype/src/type.ts:835
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
- Ensure the receiver is a number type: `type('number').divisibleBy(2)`.
- If constraining integers, use `type('number.integer').divisibleBy(2)`.
- Check the message's `k` value to see which kind the receiver actually was and fix the base type expression.
Example fix
// before
const T = type('string').divisibleBy(2); // throws: cannot apply divisibility to string
// after
const T = type('number').divisibleBy(2); Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the receiver is numeric before chaining
const base = type('number'); // not string/object/union
const T = base.divisibleBy(2); Type guard
function isNumberType(t) {
try { return t.expression.startsWith('number'); } catch { return false; }
} Try / catch
try {
const T = maybeType.divisibleBy(2);
} catch (e) {
if (e instanceof OmpTypeError && e.message.startsWith('cannot apply divisibility')) {
// use a numeric base type instead
} else throw e;
} Prevention
- Only chain numeric constraints (divisibleBy, min, max, positive) off explicit `type('number')` bases.
- Avoid fluent chains on unions — constraints apply to the whole union kind.
- Name numeric-constraint builders in one module so misuse is reviewable.
When it happens
Trigger: Calling `.divisibleBy(2)` on a non-number type, e.g. `type('string').divisibleBy(2)`, `type('boolean').divisibleBy(1)`, or chaining it onto an object/union type.
Common situations: Chaining constraint builders fluently and landing on the wrong base type; intending `type('number').divisibleBy(...)` but the expression resolves to a union or string due to a wrong type expression.
Related errors
- divisor must be non-zero
- pipe operands must be functions or Types
- Invalid pattern: {err}
- No messages to continue from
- Cannot continue from message role: assistant
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/903358bbae945352.
Report an issue: GitHub.