can1357/oh-my-pi · error · OmpTypeError
numeric range intersection is unsatisfiable
Error message
numeric range intersection is unsatisfiable
What it means
Intersecting two number types intersects their ranges (min = max of mins, max = min of maxs) while tracking exclusive bounds. The throw fires when the resulting range is empty: min > max, or min === max with an exclusive bound on either side (so no value can equal the single point).
Source
Thrown at packages/omptype/src/type.ts:2097
: "keep";
const index = a.index && b.index ? intersect(a.index, b.index) : (a.index ?? b.index);
return { k: "object", props, index, extras };
}
if (a.k === "string" && b.k === "string") {
const min = maxOf(a.min, b.min);
const max = minOf(a.max, b.max);
if (min !== undefined && max !== undefined && min > max) {
throw new OmpTypeError("string length intersection is unsatisfiable");
}
return { k: "string", min, max, url: a.url || b.url };
}
if (a.k === "number" && b.k === "number") {
const min = maxOf(a.min, b.min);
const max = minOf(a.max, b.max);
const xmin = min !== undefined && ((a.min === min && a.xmin === true) || (b.min === min && b.xmin === true));
const xmax = max !== undefined && ((a.max === max && a.xmax === true) || (b.max === max && b.xmax === true));
if (min !== undefined && max !== undefined && (min > max || (min === max && (xmin || xmax)))) {
throw new OmpTypeError("numeric range intersection is unsatisfiable");
}
if (a.divisor !== undefined && b.divisor !== undefined && a.divisor !== b.divisor) {
return { k: "intersection", members: [a, b] };
}
return {
k: "number",
int: a.int || b.int,
divisor: a.divisor ?? b.divisor,
min,
max,
xmin,
xmax,
};
}
if (a.k === "array" && b.k === "array") {
const min = maxOf(a.min, b.min);
const max = minOf(a.max, b.max);
if (min !== undefined && max !== undefined && min > max) {View on GitHub (pinned to 9690622007)
Solutions
- Widen one range so a non-empty overlap exists
- Drop the redundant range constraint from one operand
- Use exclusive vs inclusive bounds deliberately: change gt/lt to gte/lte if a boundary value is legal
- Catch OmpTypeError and report both ranges to the user
Example fix
// before intersect(number().gt(5), number().lt(5)); // after intersect(number().gte(5), number().lt(5));
Defensive patterns
Strategy: validation
Validate before calling
function numberRangeOk(specs) {
const min = Math.max(...specs.map(s => s.min ?? -Infinity));
const max = Math.min(...specs.map(s => s.max ?? Infinity));
if (min > max) return false;
if (min === max && (specs.some(s => s.xmin) || specs.some(s => s.xmax))) return false;
return true;
} 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 === 'numeric range intersection is unsatisfiable') {
throw new Error(`Numeric ranges do not overlap: ${describe(a)} vs ${describe(b)}`);
}
throw err;
} Prevention
- Verify range overlap whenever two layers constrain the same numeric option
- Be deliberate about exclusive vs inclusive bounds (gt/lt vs gte/lte); single-point ranges need inclusive bounds
- Derive bounds from one source of truth rather than independent constants
When it happens
Trigger: intersect(number().min(10), number().max(5)); or intersect(number().gt(5), number().lt(5)) — point range excluded by exclusivity; incompatible divisors are handled separately (kept as an intersection), so this is purely range emptiness.
Common situations: Two validation layers each constraining the same numeric option from opposite directions (min from config A, max from config B); exclusive bounds squeezed to a single point after an edit; percentage/0-1 range checks colliding with absolute caps.
Related errors
- numeric bound must be finite
- string length intersection is unsatisfiable
- array length intersection is unsatisfiable
- tmpfiles option ttl must be between 60 seconds and 48 hours
- Invalid number: ${rawValue}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c3fb193c43f35590.
Report an issue: GitHub.