fix(schema): preserve root metadata on fallback (#4178)

This commit is contained in:
yuyua9 2026-05-20 21:46:56 +08:00 committed by GitHub
commit 834f96d462
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 16 additions and 0 deletions

View file

@ -281,6 +281,16 @@ def resolve_root_ref(schema: dict[str, Any]) -> dict[str, Any]:
if def_name in defs:
# Create a new schema by copying the referenced definition
resolved = dict(defs[def_name])
# Preserve root-level sibling metadata from the original schema.
# Pydantic may put user-facing fields such as title, description,
# default, or examples next to the root $ref. Those fields still
# describe the root schema even when we can only resolve that
# root reference for circular schemas.
for key, value in schema.items():
if key not in {"$ref", "$defs"}:
resolved[key] = value
# Preserve $defs for nested references (other fields may still use them)
resolved["$defs"] = defs
return resolved

View file

@ -120,6 +120,9 @@ class TestDereferenceRefs:
}
},
"$ref": "#/$defs/Node",
"title": "Tree node",
"description": "A recursive tree node.",
"examples": [{"children": []}],
}
result = dereference_refs(schema)
@ -127,6 +130,9 @@ class TestDereferenceRefs:
# Root should be resolved but nested refs preserved
assert result.get("type") == "object"
assert "$defs" in result # $defs preserved for circular refs
assert result["title"] == "Tree node"
assert result["description"] == "A recursive tree node."
assert result["examples"] == [{"children": []}]
def test_falls_back_for_circular_json_pointer_refs(self):
"""Test that circular JSON Pointer $ref (non-$defs) does not crash.