@@ -535,6 +535,12 @@ export class Collection<Schema extends StandardSchemaV1> {
535535 descriptor : PropertyDescriptor
536536 } > = [ ]
537537
538+ // Track visited records by primary key to detect cycles
539+ // in self-referencing relations. Only strip relation values
540+ // when revisiting a record (i.e. an actual cycle), not for
541+ // all nested records indiscriminately.
542+ const visited = new Set < string > ( )
543+
538544 const sanitize = (
539545 value : unknown ,
540546 path : Array < string | number | symbol > = [ ] ,
@@ -544,7 +550,14 @@ export class Collection<Schema extends StandardSchemaV1> {
544550 }
545551
546552 if ( isObject ( value ) ) {
547- const relations = isRecord ( value ) ? value [ kRelationMap ] : undefined
553+ const record = isRecord ( value ) ? value : undefined
554+ const isRevisit = record != null && visited . has ( record [ kPrimaryKey ] )
555+
556+ if ( record && ! isRevisit ) {
557+ visited . add ( record [ kPrimaryKey ] )
558+ }
559+
560+ const relations = record ? record [ kRelationMap ] : undefined
548561
549562 return Object . fromEntries (
550563 Reflect . ownKeys ( value ) . map ( ( key ) => {
@@ -569,7 +582,10 @@ export class Collection<Schema extends StandardSchemaV1> {
569582
570583 const relation = relations ?. get ( key )
571584
572- if ( relation && childValue != null ) {
585+ // Only strip relation values when revisiting a record
586+ // to break self-referencing cycles. Non-circular nested
587+ // relations are left intact for proper schema validation.
588+ if ( isRevisit && relation && childValue != null ) {
573589 propertiesToRestore . push ( {
574590 path : childPath ,
575591 descriptor : Object . getOwnPropertyDescriptor ( value , key ) ! ,
@@ -586,6 +602,7 @@ export class Collection<Schema extends StandardSchemaV1> {
586602 }
587603
588604 const sanitizedInitialValues = sanitize ( initialValues )
605+
589606 return {
590607 sanitizedInitialValues,
591608 /**
0 commit comments