Skip to content

TypeError: Invalid value used as weak map key in schema UI when mergeAllOf returns non-object #3022

@preetpatel

Description

@preetpatel

To Reproduce

Any OpenAPI spec where allOf intersection produces a conflict (mismatched type, format, or const values between allOf members) will trigger this issue

Current vs. Expected behavior

getSchemaId() in dist/ui/schema/index.js crashes with TypeError: Invalid value used as weak map key when a non-object value (e.g. false) reaches the WeakMap operations.

The root cause is that intersection() in dist/utils/merge-schema.js can return false (line 75: if (!deepEqual(result[key], value)) return false), and this value propagates through mergeAllOf() into scanRefs() and eventually getSchemaId(). The boolean guard (typeof schema === "boolean") handles true/false, but the related functions isVisible(), base(), and scanRefs() have the same guard pattern and would fail on null or undefined if those ever reach them through schema dereferencing.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:47:03 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6031
  Available memory (MB): 36864
  Available CPU cores: 14
Binaries:
  Node: 22.21.1
  npm: 10.9.4
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 16.1.6 // Latest available version is detected (16.1.6).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: standalone

Which area(s) are affected? (Select all that apply)

Integrations (e.g OpenAPI, Typescript DocsGen)

Additional context

Bug was not present on 10.3.3 but 10.3.7 causes the crash

This is the patch I've added for now in my codebase:

diff --git a/node_modules/fumadocs-openapi/dist/ui/schema/index.js b/node_modules/fumadocs-openapi/dist/ui/schema/index.js
index f8bf5c7..a7c1148 100644
--- a/node_modules/fumadocs-openapi/dist/ui/schema/index.js
+++ b/node_modules/fumadocs-openapi/dist/ui/schema/index.js
@@ -65,7 +65,7 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
 	let _counter = 0;
 	const autoIds = /* @__PURE__ */ new WeakMap();
 	function getSchemaId(schema) {
-		if (typeof schema === "boolean") return String(schema);
+		if (schema === null || schema === void 0 || typeof schema !== "object") return String(schema);
 		const raw = ctx.schema.getRawRef(schema);
 		if (raw) return raw;
 		const prev = autoIds.get(schema);
@@ -75,13 +75,13 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
 		return generated;
 	}
 	function isVisible(schema) {
-		if (typeof schema === "boolean") return true;
+		if (schema === null || schema === void 0 || typeof schema !== "object") return true;
 		if (schema.writeOnly) return writeOnly ?? false;
 		if (schema.readOnly) return readOnly ?? false;
 		return true;
 	}
 	function base(schema) {
-		if (typeof schema === "boolean") {
+		if (schema === null || schema === void 0 || typeof schema !== "object") {
 			const name = schema ? "any" : "never";
 			return {
 				typeName: name,
@@ -98,7 +98,7 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
 	}
 	function scanRefs(id, schema) {
 		if (id in refs) return;
-		if (typeof schema === "boolean") {
+		if (schema === null || schema === void 0 || typeof schema !== "object") {
 			refs[id] = {
 				type: "primitive",
 				...base(schema)
@@ -175,7 +175,12 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
 			return;
 		}
 		if (schema.allOf) {
-			scanRefs(id, mergeAllOf(schema));
+			const merged = mergeAllOf(schema);
+			if (merged !== null && merged !== void 0 && typeof merged === "object") {
+				scanRefs(id, merged);
+			} else {
+				refs[id] = { type: "primitive", ...base(schema) };
+			}
 			return;
 		}
 		if (schema.type === "object") {

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions