can1357/oh-my-pi · error · OmpTypeError
literal is excluded by intersection
Error message
literal is excluded by intersection
What it means
parseIntersection detected a numeric literal intersected with a number constraint it cannot satisfy: integer-ness, a % divisor, or a min/max bound. E.g. '2.5 & number.integer', '3 & number % 2', '0 & number > 1'. The result would be the never type, so the library refuses at parse time rather than producing a schema that matches nothing.
Source
Thrown at packages/omptype/src/ir.ts:413
return { k: "union", members };
}
parseIntersection(): IR {
const first = this.parseBounded();
if (!this.#eatOp("&")) return first;
const members = [first, this.parseBounded()];
while (this.#eatOp("&")) members.push(this.parseBounded());
const literal = members.find((member): member is Extract<IR, { k: "lit" }> => member.k === "lit");
if (literal && typeof literal.v === "number") {
for (const member of members) {
if (
member.k === "number" &&
((member.int && !Number.isInteger(literal.v)) ||
(member.divisor !== undefined && literal.v % member.divisor !== 0) ||
(member.min !== undefined && (member.xmin ? literal.v <= member.min : literal.v < member.min)) ||
(member.max !== undefined && (member.xmax ? literal.v >= member.max : literal.v > member.max)))
) {
throw new OmpTypeError("literal is excluded by intersection");
}
}
return literal;
}
return { k: "intersection", members };
}
/**
* `NUM CMP base (CMP NUM)?` or `base (CMP NUM)?`, with `[]*` postfix on the
* base AND after a trailing bound — `string>0[]` is an array of bounded
* strings, matching ArkType precedence (bounds bind tighter than `[]`).
*/
parseBounded(): IR {
const t = this.#peek();
const t1 = this.#peek(1);
if ((t?.t === "num" || t?.t === "date") && t1?.t === "op" && (t1.v === "<" || t1.v === "<=")) {
const lo = t.v;
this.#pos += 2;View on GitHub (pinned to 9690622007)
Solutions
- Make the literal satisfy the constraint: use an integer for '& number.integer', a multiple for '% n', and a value inside the bounds.
- If the constant was meant to be independent, replace '&' with a union '|' or remove the redundant constraint.
- Recompute bounds/divisor so they're consistent with the literal, ideally deriving both from one source constant.
- If never is genuinely intended, use the explicit 'never' keyword instead of a contradictory intersection.
Example fix
// before
schema.parse("3 & number % 2"); // never
// after
schema.parse("3 & number % 1"); // or just 3, or 4 & number % 2 Defensive patterns
Strategy: validation
Validate before calling
function literalFits(v, { int, divisor, min, max, xmin, xmax }) {
if (int && !Number.isInteger(v)) return false;
if (divisor !== undefined && v % divisor !== 0) return false;
if (min !== undefined && (xmin ? v <= min : v < min)) return false;
if (max !== undefined && (xmax ? v >= max : v > max)) return false;
return true;
} Try / catch
try {
const schema = parse(def);
} catch (e) {
if (String(e.message) === "literal is excluded by intersection") {
// drop the conflicting constraint or correct the literal
}
throw e;
} Prevention
- Derive literals and their constraints from the same source constant so they can't drift.
- Check divisibility/integer-ness of constants before intersecting them with refined number types.
- Use 'never' explicitly if an empty type is intended.
When it happens
Trigger: Intersections of a number literal with 'number.integer' when the literal has a fraction; with a '% n' divisor when literal % n !== 0; or with a bound (>, >=, <, <=, possibly flipped via the left-bound form) that excludes the literal.
Common situations: Combining a constant with a refinement written by a different code path (template-built constraints drifting out of sync with the literal); refactoring bounds without updating co-declared literals; generically composing 'value & number >= minValue' where value < minValue.
Related errors
- No files were modified.
- The first line of the patch must be '*** Begin Patch'
- The last line of the patch must be '*** End Patch'
- Update file hunk for path '${path}' is empty
- '${firstLine}' is not a valid hunk header. Valid hunk header
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e5121bc9d4a2b2ea.
Report an issue: GitHub.