{"record":{"id":"c3fb193c43f35590","repo":"can1357/oh-my-pi","slug":"numeric-range-intersection-is-unsatisfiable","errorCode":null,"errorMessage":"numeric range intersection is unsatisfiable","messagePattern":"numeric range intersection is unsatisfiable","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":2097,"sourceCode":"\t\t\t\t\t: \"keep\";\n\t\tconst index = a.index && b.index ? intersect(a.index, b.index) : (a.index ?? b.index);\n\t\treturn { k: \"object\", props, index, extras };\n\t}\n\tif (a.k === \"string\" && b.k === \"string\") {\n\t\tconst min = maxOf(a.min, b.min);\n\t\tconst max = minOf(a.max, b.max);\n\t\tif (min !== undefined && max !== undefined && min > max) {\n\t\t\tthrow new OmpTypeError(\"string length intersection is unsatisfiable\");\n\t\t}\n\t\treturn { k: \"string\", min, max, url: a.url || b.url };\n\t}\n\tif (a.k === \"number\" && b.k === \"number\") {\n\t\tconst min = maxOf(a.min, b.min);\n\t\tconst max = minOf(a.max, b.max);\n\t\tconst xmin = min !== undefined && ((a.min === min && a.xmin === true) || (b.min === min && b.xmin === true));\n\t\tconst xmax = max !== undefined && ((a.max === max && a.xmax === true) || (b.max === max && b.xmax === true));\n\t\tif (min !== undefined && max !== undefined && (min > max || (min === max && (xmin || xmax)))) {\n\t\t\tthrow new OmpTypeError(\"numeric range intersection is unsatisfiable\");\n\t\t}\n\t\tif (a.divisor !== undefined && b.divisor !== undefined && a.divisor !== b.divisor) {\n\t\t\treturn { k: \"intersection\", members: [a, b] };\n\t\t}\n\t\treturn {\n\t\t\tk: \"number\",\n\t\t\tint: a.int || b.int,\n\t\t\tdivisor: a.divisor ?? b.divisor,\n\t\t\tmin,\n\t\t\tmax,\n\t\t\txmin,\n\t\t\txmax,\n\t\t};\n\t}\n\tif (a.k === \"array\" && b.k === \"array\") {\n\t\tconst min = maxOf(a.min, b.min);\n\t\tconst max = minOf(a.max, b.max);\n\t\tif (min !== undefined && max !== undefined && min > max) {","sourceCodeStart":2079,"sourceCodeEnd":2115,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L2079-L2115","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nintersect(number().gt(5), number().lt(5));\n// after\nintersect(number().gte(5), number().lt(5));","handlingStrategy":"validation","validationCode":"function numberRangeOk(specs) {\n  const min = Math.max(...specs.map(s => s.min ?? -Infinity));\n  const max = Math.min(...specs.map(s => s.max ?? Infinity));\n  if (min > max) return false;\n  if (min === max && (specs.some(s => s.xmin) || specs.some(s => s.xmax))) return false;\n  return true;\n}","typeGuard":"const isOmpTypeError = (e: unknown): e is OmpTypeError => e instanceof OmpTypeError;","tryCatchPattern":"try {\n  const t = intersect(a, b);\n} catch (err) {\n  if (err instanceof OmpTypeError && err.message === 'numeric range intersection is unsatisfiable') {\n    throw new Error(`Numeric ranges do not overlap: ${describe(a)} vs ${describe(b)}`);\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["types","number","range","validation","omptype"],"backgroundTag":"unsatisfiable-type-intersection","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}