can1357/oh-my-pi · error · OmpTypeError

intersection of ${a.expected} and ${b.expected} is unsatisfi

Error message

intersection of ${a.expected} and ${b.expected} is unsatisfiable

What it means

When intersecting two instance types (constructed via instanceof-style checks), the library returns the narrower constructor if one is a subclass of the other. If the constructors are unrelated (neither prototype chain contains the other), no value can be an instance of both, so it throws with the human-readable expected names of both types.

Source

Thrown at packages/omptype/src/type.ts:2126

			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) {
			throw new OmpTypeError("array length intersection is unsatisfiable");
		}
		return { k: "array", el: intersect(a.el, b.el), min, max };
	}
	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 };
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Use the common subclass if one actually extends the other
  2. Replace the intersection with a union if either instance is acceptable
  3. Model the constraint with a single class or an object/structural type instead of two instance checks
  4. Deduplicate class copies so the same constructor identity is used

Example fix

// before
intersect(instance(Error), instance(TypeError)); // TypeError extends Error: OK
intersect(instance(Error), instance(Map)); // throws
// after
intersect(instance(TypeError), instance(Error)); // subtype first, or intersect related ctors only
Defensive patterns

Strategy: type-guard

Validate before calling

function instancesCompatible(a, b) {
  return a.ctor === b.ctor || a.ctor.prototype instanceof b.ctor || b.ctor.prototype instanceof a.ctor;
}

Type guard

const isOmpTypeError = (e: unknown): e is OmpTypeError => e instanceof OmpTypeError;

Try / catch

try {
  const t = intersect(instanceA, instanceB);
} catch (err) {
  if (err instanceof OmpTypeError && err.message.includes('is unsatisfiable')) {
    // use a union or a structural (object) type instead
  } else throw err;
}

Prevention

When it happens

Trigger: intersect(instance(Date), instance(Map)); or intersecting a class with an unrelated class after a refactor renamed/moved one; two versioned copies of the same class from different module instances (prototype chains differ).

Common situations: Refinements asserting instanceof checks on classes that were never in a subclass relationship; duplicate class copies from multiple bundler chunks or dual package installs; intersecting a base-class refinement with a sibling-class refinement.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/47685aaa347140bb. Report an issue: GitHub.