Skip to content

Conversation

@mike-taylor99
Copy link
Contributor

Fix circular references in JSON Schema discriminated unions with polymorphic-models-strategy

Problem

When using polymorphic-models-strategy: "oneOf" (or "anyOf") with discriminated unions, the JSON Schema emitter generates circular references that cause validation errors:

  1. Base model (e.g., Pet) emits oneOf: [Cat, Dog]
  2. Derived models (e.g., Cat, Dog) emit allOf: [{ $ref: "Pet.json" }]
  3. This creates a cycle: Pet → Cat → Pet (via oneOf and allOf)

JSON Schema validators reject these circular references, making it impossible to validate payloads against the discriminated union schemas.

Solution

When a model extends a base model that uses the discriminated union strategy:

  • Don't use allOf to reference the base model (avoiding circular references)
  • Inline all base properties directly into the derived model schema
  • The base model still emits only oneOf/anyOf without properties

Example

Before (circular reference):

// Pet.json
{ "oneOf": [{"$ref": "Cat.json"}], "properties": {"name": ...}, ... }

// Cat.json  
{ "allOf": [{"$ref": "Pet.json"}], "properties": {"meow": ...}, ... }

After (no circular reference):

// Pet.json
{ "oneOf": [{"$ref": "Cat.json"}] }

// Cat.json
{ "properties": {"name": ..., "kind": "cat", "meow": ...}, "required": ["name", "kind"] }

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 21, 2025

Open in StackBlitz

npm i https://pkg.pr.new/microsoft/typespec/@typespec/json-schema@9056

commit: cb6fb16

@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

All changed packages have been documented.

  • @typespec/json-schema
Show changes

@typespec/json-schema - fix ✏️

avoid circular references in discriminated unions with polymorphic-models-strategy

@timotheeguerin
Copy link
Member

/azp run typespec - pr tools

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@azure-sdk
Copy link
Collaborator

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

Copy link
Member

@timotheeguerin timotheeguerin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • from offline talk update the doc to specify what this fully does

@@ -0,0 +1,7 @@
---
changeKind: fix
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
changeKind: fix
changeKind: internal

can be internal as the original change wasn't released in regular version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants