{"record":{"id":"20f2f7929351ff7b","repo":"can1357/oh-my-pi","slug":"intersection-has-no-satisfiable-branches","errorCode":null,"errorMessage":"intersection has no satisfiable branches","messagePattern":"intersection has no satisfiable branches","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":2037,"sourceCode":"\t\t}\n\t\tconst schema = a.schema as InternalType;\n\t\treturn embed(makeType(intersect(schema.ir, b), schema[kSteps], metaOf(schema)));\n\t}\n\tif (b.k === \"sub\" && b.schema.hasSteps) return intersect(b, a);\n\tif (a.k === \"union\" || b.k === \"union\") {\n\t\tconst union = a.k === \"union\" ? a : b.k === \"union\" ? b : undefined;\n\t\tif (union === undefined) throw new OmpTypeError(\"union intersection invariant failed\");\n\t\tconst branches = union.members;\n\t\tconst other = a.k === \"union\" ? b : a;\n\t\tconst members: IR[] = [];\n\t\tfor (const branch of branches) {\n\t\t\ttry {\n\t\t\t\tmembers.push(intersect(branch, other));\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof OmpTypeError)) throw error;\n\t\t\t}\n\t\t}\n\t\tif (members.length === 0) throw new OmpTypeError(\"intersection has no satisfiable branches\");\n\t\treturn members.length === 1 ? members[0] : { k: \"union\", members };\n\t}\n\tif (a.k === \"lit\") {\n\t\tif (walk(b, a.v) instanceof OmpErrors) throw new OmpTypeError(\"literal is excluded by the intersection\");\n\t\treturn a;\n\t}\n\tif (b.k === \"lit\") return intersect(b, a);\n\tif (a.k === \"object\" && b.k === \"object\") {\n\t\tconst props = [...a.props];\n\t\tfor (const bp of b.props) {\n\t\t\tconst index = props.findIndex(prop => prop.key === bp.key);\n\t\t\tif (index < 0) props.push(bp);\n\t\t\telse {\n\t\t\t\tconst ap = props[index];\n\t\t\t\tconst required = (!ap.opt && !ap.hasDefault) || (!bp.opt && !bp.hasDefault);\n\t\t\t\tif (ap.hasDefault && bp.hasDefault && !Object.is(ap.def, bp.def)) {\n\t\t\t\t\tthrow new OmpTypeError(\n\t\t\t\t\t\t`ParseError: Invalid intersection of default values ${String(ap.def)} & ${String(bp.def)}`,","sourceCodeStart":2019,"sourceCodeEnd":2055,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L2019-L2055","documentation":"This error is thrown by the intersection algorithm in packages/omptype when combining two intersection-typed values: every candidate branch combination fails with an OmpTypeError, so no satisfiable member remains. The library treats an intersection whose branches are all impossible as a type-construction error rather than silently producing `never`, so it fails fast at type build/parse time.","triggerScenarios":"Calling the intersect/intersection helper (or building a schema that intersects two types) where every pairwise intersect(branch, other) call throws an OmpTypeError — e.g. intersecting string with number, or object shapes with conflicting required keys.","commonSituations":"Merging two config schemas that declare incompatible base types for the same option; combining a base type with a refinement whose domain no longer overlaps after a library upgrade; intersecting a tuple with mismatched element types.","solutions":["Remove or relax one of the intersected types so at least one branch combination is satisfiable","Check that both operands share the same value domain (string vs string, number vs number) before intersecting","Catch OmpTypeError around the intersect call and surface which pair of types failed","If the intersection is intentionally impossible, use a union or a single type instead"],"exampleFix":"// before\nconst t = intersect(string().min(5), string().max(2));\n// after\nconst t = intersect(string().min(1), string().max(2));","handlingStrategy":"try-catch","validationCode":"function canIntersect(a, b) {\n  try { intersect(a, b); return true; } catch (e) {\n    return e instanceof OmpTypeError ? false : throw e;\n  }\n}","typeGuard":"const isOmpTypeError = (e: unknown): e is OmpTypeError => e instanceof OmpTypeError;","tryCatchPattern":"let combined;\ntry {\n  combined = intersect(typeA, typeB);\n} catch (err) {\n  if (err instanceof OmpTypeError) {\n    throw new Error(`Cannot intersect ${describe(typeA)} with ${describe(typeB)}: ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Confirm both operands share the same base kind before intersecting","Prefer single-builder constraints (.min/.max on one type) over intersecting two constrained types","Add a unit test for every schema intersection you ship","Catch OmpTypeError at schema-construction time and fail fast with both type descriptions"],"tags":["types","intersection","schema","omptype"],"backgroundTag":"unsatisfiable-type-intersection","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}