can1357/oh-my-pi · error · OmpTypeError
intersection of ${leftDomain} and ${rightDomain} is unsatisf
Error message
intersection of ${leftDomain} and ${rightDomain} is unsatisfiable What it means
Generic domain-conflict check near the end of the intersection algorithm: if both operands have a defined value domain (from domainOf) and the domains differ, no value can belong to both, so the intersection is rejected. This is the catch-all for kind combinations not handled by the earlier structural branches.
Source
Thrown at packages/omptype/src/type.ts:2138
if (a.k === "tuple" && b.k === "tuple") return intersectTuples(a, b);
if (a.k === "tuple" && b.k === "array") return intersectTupleWithArray(a, b);
if (a.k === "array" && b.k === "tuple") return intersectTupleWithArray(b, a);
if (a.k === "instance" && b.k === "instance") {
if (a.ctor === b.ctor || a.ctor.prototype instanceof b.ctor) return a;
if (b.ctor.prototype instanceof a.ctor) return b;
throw new OmpTypeError(`intersection of ${a.expected} and ${b.expected} is unsatisfiable`);
}
if (a.k === b.k && ["null", "undefined", "boolean", "bigint", "symbol", "anyobject"].includes(a.k)) return a;
if (
(a.k === "object" && (b.k === "array" || b.k === "tuple")) ||
(b.k === "object" && (a.k === "array" || a.k === "tuple"))
) {
return { k: "intersection", members: [a, b] };
}
const leftDomain = domainOf(a);
const rightDomain = domainOf(b);
if (leftDomain !== undefined && rightDomain !== undefined && leftDomain !== rightDomain) {
throw new OmpTypeError(`intersection of ${leftDomain} and ${rightDomain} is unsatisfiable`);
}
if (a.k === "anyobject" && rightDomain === "object") return b;
if (b.k === "anyobject" && leftDomain === "object") return a;
const members = [...(a.k === "intersection" ? a.members : [a]), ...(b.k === "intersection" ? b.members : [b])];
return { k: "intersection", members };
}
/** Reduce parsed unions/intersections to their observable semantic form. */
function normalizeIR(ir: IR): IR {
switch (ir.k) {
case "intersection": {
const members = ir.members.map(normalizeIR);
if (members.length === 0) return { k: "unknown" };
return members.slice(1).reduce(intersect, members[0]);
}
case "union": {
const members: IR[] = [];
let changed = false;View on GitHub (pinned to 9690622007)
Solutions
- Ensure both operands share the same base domain before intersecting
- Inspect each operand with the library's type inspection to confirm the intended kinds
- Fix operand ordering/arguments if a mixup passed the wrong type
- Catch OmpTypeError and log both expected domains to identify the mismatch
Example fix
// before intersect(string(), number()); // after intersect(string().url(), string().min(1));
Defensive patterns
Strategy: validation
Validate before calling
// compare kinds before intersecting
function domainsCompatible(a, b) {
const da = domainOf(a), db = domainOf(b);
return da === undefined || db === undefined || da === db;
} Type guard
const isOmpTypeError = (e: unknown): e is OmpTypeError => e instanceof OmpTypeError;
Try / catch
try {
const t = intersect(a, b);
} catch (err) {
if (err instanceof OmpTypeError && err.message.includes('domain')) {
logger.warn('intersecting incompatible domains', { left: describe(a), right: describe(b) });
} else throw err;
} Prevention
- Inspect both operands' kinds before intersecting; intersect only same-domain types
- Fix argument order/passing — most domain conflicts come from supplying the wrong schema
- Add a schema-construction test that exercises each intersection path
When it happens
Trigger: intersect(string(), number()); intersect(lit(1), string()); intersecting any two types whose domains (e.g. 'string' vs 'number', 'object' vs 'string') disagree and have no earlier special case.
Common situations: Wiring the wrong schema field into an intersection (name/positional mixup); a refactor changed one operand's base kind; intersecting an optional/undefined-domain type with a string-constrained type.
Related errors
- intersection has no satisfiable branches
- literal is excluded by the intersection
- ParseError: Invalid intersection of default values ${String(
- intersection of ${a.expected} and ${b.expected} is unsatisfi
- tuple length intersection is unsatisfiable
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/55b14c0b3407ec28.
Report an issue: GitHub.