agent_patch
runs/2026-02-27__21-30-28__gpt-5-3-codex/flux-pr-5574/flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/agent-logs/agent.patch
7201 bytes
diff --git a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/docs/content/metadata.mdx b/app/packages/docs/content/metadata.mdx
index c31ccad..a19ddd9 100644
--- a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/docs/content/metadata.mdx
+++ b/app/packages/docs/content/metadata.mdx
@@ -39,7 +39,7 @@ myRegistry.add(mySchema, { description: "A cool schema!" }); // ✅
myRegistry.add(mySchema, { description: 123 }); // ❌
```
-> **Special handling for `id`** — Zod registries treat the `id` property specially. An `Error` will be thrown if multiple schemas are registered with the same `id` value. This is true for all registries, including the global registry.
+> **Special handling for `id`** — Zod registries treat the `id` property specially. Multiple schemas can be registered with the same `id`, but `z.toJSONSchema(registry)` will throw if different schemas with the same `id` are converted together.
### `.register()`
diff --git a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/classic/tests/registries.test.ts b/app/packages/zod/src/v4/classic/tests/registries.test.ts
index af0c4c3..5c64f06 100644
--- a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/classic/tests/registries.test.ts
+++ b/app/packages/zod/src/v4/classic/tests/registries.test.ts
@@ -46,6 +46,18 @@ test("z.registry no metadata", () => {
expect(fieldRegistry.has(a)).toEqual(true);
});
+test("z.registry allows duplicate ids for different schemas", () => {
+ const fieldRegistry = z.registry<{ id: string }>();
+ const a = z.string();
+ const b = z.number();
+
+ fieldRegistry.add(a, { id: "shared" });
+ fieldRegistry.add(b, { id: "shared" });
+
+ expect(fieldRegistry.get(a)?.id).toEqual("shared");
+ expect(fieldRegistry.get(b)?.id).toEqual("shared");
+});
+
test("z.registry with schema constraints", () => {
const fieldRegistry = z.registry<{ name: string; description: string }, z.ZodString>();
diff --git a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/classic/tests/to-json-schema.test.ts b/app/packages/zod/src/v4/classic/tests/to-json-schema.test.ts
index 45bf823..cd4be54 100644
--- a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/classic/tests/to-json-schema.test.ts
+++ b/app/packages/zod/src/v4/classic/tests/to-json-schema.test.ts
@@ -2311,6 +2311,14 @@ test("basic registry", () => {
`);
});
+test("registry conversion throws on duplicate ids across different schemas", () => {
+ const myRegistry = z.registry<{ id: string }>();
+ myRegistry.add(z.string(), { id: "shared" });
+ myRegistry.add(z.number(), { id: "shared" });
+
+ expect(() => z.toJSONSchema(myRegistry)).toThrow('Duplicate schema id "shared" found during JSON Schema conversion');
+});
+
test("_ref", () => {
// const a = z.promise(z.string().describe("a"));
const a = z.toJSONSchema(z.promise(z.string().describe("a")));
diff --git a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/core/json-schema-processors.ts b/app/packages/zod/src/v4/core/json-schema-processors.ts
index 96187fa..68d8fea 100644
--- a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/core/json-schema-processors.ts
+++ b/app/packages/zod/src/v4/core/json-schema-processors.ts
@@ -606,9 +606,18 @@ export function toJSONSchema(
const registry = input as $ZodRegistry<{ id?: string | undefined }>;
const ctx = initializeContext({ ...params, processors: allProcessors });
const defs: any = {};
+ const registryEntries: [string, schemas.$ZodType][] = [];
+
+ for (const [id, idSet] of registry._idmap.entries()) {
+ if (idSet.size > 1) {
+ throw new Error(`Duplicate schema id "${id}" found during JSON Schema conversion`);
+ }
+ const schema = idSet.values().next().value as schemas.$ZodType | undefined;
+ if (schema) registryEntries.push([id, schema]);
+ }
// First pass: process all schemas to build the seen map
- for (const entry of registry._idmap.entries()) {
+ for (const entry of registryEntries) {
const [_, schema] = entry;
process(schema, ctx as any);
}
@@ -624,7 +633,7 @@ export function toJSONSchema(
ctx.external = external;
// Second pass: emit each schema
- for (const entry of registry._idmap.entries()) {
+ for (const entry of registryEntries) {
const [key, schema] = entry;
extractDefs(ctx as any, schema);
schemas[key] = finalize(ctx as any, schema);
diff --git a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/core/registries.ts b/app/packages/zod/src/v4/core/registries.ts
index b8cfc34..3d32194 100644
--- a/tmp/agent-patch-flux-pr-5574.1-of-1.2026-02-27__21-30-28__gpt-5-3-codex/app/packages/zod/src/v4/core/registries.ts
+++ b/app/packages/zod/src/v4/core/registries.ts
@@ -28,19 +28,34 @@ export class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema exten
_meta!: Meta;
_schema!: Schema;
_map: WeakMap<Schema, $replace<Meta, Schema>> = new WeakMap();
- _idmap: Map<string, Schema> = new Map();
+ _idmap: Map<string, Set<Schema>> = new Map();
+ _schemaIdMap: WeakMap<Schema, string> = new WeakMap();
add<S extends Schema>(
schema: S,
..._meta: undefined extends Meta ? [$replace<Meta, S>?] : [$replace<Meta, S>]
): this {
const meta: any = _meta[0];
+ const prevId = this._schemaIdMap.get(schema);
+ if (prevId) {
+ const prevSet = this._idmap.get(prevId);
+ if (prevSet) {
+ prevSet.delete(schema);
+ if (prevSet.size === 0) this._idmap.delete(prevId);
+ }
+ this._schemaIdMap.delete(schema);
+ }
+
this._map.set(schema, meta!);
if (meta && typeof meta === "object" && "id" in meta) {
- if (this._idmap.has(meta.id!)) {
- throw new Error(`ID ${meta.id} already exists in the registry`);
+ const id = meta.id!;
+ const idset = this._idmap.get(id);
+ if (idset) {
+ idset.add(schema);
+ } else {
+ this._idmap.set(id, new Set([schema]));
}
- this._idmap.set(meta.id!, schema);
+ this._schemaIdMap.set(schema, id);
}
return this as any;
}
@@ -48,13 +63,19 @@ export class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema exten
clear(): this {
this._map = new WeakMap();
this._idmap = new Map();
+ this._schemaIdMap = new WeakMap();
return this;
}
remove(schema: Schema): this {
- const meta: any = this._map.get(schema);
- if (meta && typeof meta === "object" && "id" in meta) {
- this._idmap.delete(meta.id!);
+ const id = this._schemaIdMap.get(schema);
+ if (id) {
+ const idset = this._idmap.get(id);
+ if (idset) {
+ idset.delete(schema);
+ if (idset.size === 0) this._idmap.delete(id);
+ }
+ this._schemaIdMap.delete(schema);
}
this._map.delete(schema);
return this;