You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
With ReferenceHandler.IgnoreCycles, registering the factory changes serialized output when a cycle passes through an unclaimed (polymorphic) ancestor #90
JsonRequiredConditionallyConverter.Write (JsonRequiredConditionally/JsonRequiredConditionallyConverter.cs:104-105) calls JsonSerializer.Serialize(writer, value, plainOptions). That starts a fresh serialization with its own reference/cycle tracker.
When the claimed type is the root, this does no harm, because everything below it is written by that one inner call.
I reproduced both on net10.0 against HEAD b518593. PR #87 will probably fix the root-list case. The polymorphic case remains.
Why it matters
Registering a validation library should not change the JSON it writes. Here it silently adds a level of nesting and moves where the cycle is cut. Anything that compares, hashes, or round-trips the output sees different results depending on whether the factory is registered. The existing test ContainmentTests.IgnoreCyclesSerializesACyclicGraphThroughAClaimedType (ContainmentTests.cs:119) only covers a cycle rooted at the claimed type.
Suggested fix / acceptance criteria
One of:
Write in a way that keeps the outer write stack's cycle detection, for example by serializing with the caller's options and a JsonTypeInfo obtained from plainOptions. Whether System.Text.Json allows this needs checking. Or:
Document in the README's IgnoreCycles paragraph that a cycle crossing an unclaimed ancestor is cut one level later.
Tests: either the polymorphic repro above serializes the same with and without the factory, or the README states the limitation.
Priority: Low. Output differs only when IgnoreCycles is used and a cycle crosses an unclaimed (polymorphic) ancestor. The JSON is still valid and a README note is an acceptable fix.
Area:JsonRequiredConditionallyConverter.Write (inner Serialize with plainOptions)
Activity
matt-edmondson commentedon Oct 29, 2026
Triage
IgnoreCyclesis used and a cycle crosses an unclaimed (polymorphic) ancestor. The JSON is still valid and a README note is an acceptable fix.JsonRequiredConditionallyConverter.Write(innerSerializewithplainOptions)JsonTypeInfo-based write can keep the outer cycle tracker. If not, document the limitation in the README'sIgnoreCyclesparagraph and add the polymorphic repro as a test.Generated by Claude Code