From bb8630ba9d2bb18d07cfe8c73445016ba4e03af6 Mon Sep 17 00:00:00 2001 From: Junhyuk Lee Date: Sat, 18 Apr 2026 18:04:45 -0500 Subject: [PATCH] fix: forward forceResolution through parseBrandedDef to prevent circular $ref When a branded Zod type (e.g. z.string().brand<'SlideId'>()) is used in multiple places in a schema, parseDef registers the inner type's def in refs.seen on first encounter. On second encounter, because parseBrandedDef did not forward the forceResolution parameter, parseDef returns a $ref instead of re-resolving. With the extract-to-root strategy this creates a self-referencing circular $ref like { $ref: '#/definitions/..._same' }. The fix passes forceResolution through parseBrandedDef so the inner type is always fully resolved when required. Fixes #1739 --- src/_vendor/zod-to-json-schema/parseDef.ts | 2 +- src/_vendor/zod-to-json-schema/parsers/branded.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_vendor/zod-to-json-schema/parseDef.ts b/src/_vendor/zod-to-json-schema/parseDef.ts index f4dd747ca..bbdbb3d42 100644 --- a/src/_vendor/zod-to-json-schema/parseDef.ts +++ b/src/_vendor/zod-to-json-schema/parseDef.ts @@ -230,7 +230,7 @@ const selectParser = ( case ZodFirstPartyTypeKind.ZodDefault: return parseDefaultDef(def, refs); case ZodFirstPartyTypeKind.ZodBranded: - return parseBrandedDef(def, refs); + return parseBrandedDef(def, refs, forceResolution); case ZodFirstPartyTypeKind.ZodReadonly: return parseReadonlyDef(def, refs); case ZodFirstPartyTypeKind.ZodCatch: diff --git a/src/_vendor/zod-to-json-schema/parsers/branded.ts b/src/_vendor/zod-to-json-schema/parsers/branded.ts index c585f2d93..f740056aa 100644 --- a/src/_vendor/zod-to-json-schema/parsers/branded.ts +++ b/src/_vendor/zod-to-json-schema/parsers/branded.ts @@ -2,6 +2,6 @@ import { ZodBrandedDef } from 'zod/v3'; import { parseDef } from '../parseDef'; import { Refs } from '../Refs'; -export function parseBrandedDef(_def: ZodBrandedDef, refs: Refs) { - return parseDef(_def.type._def, refs); +export function parseBrandedDef(_def: ZodBrandedDef, refs: Refs, forceResolution: boolean = false) { + return parseDef(_def.type._def, refs, forceResolution); }