Skip to content

Commit dc7a4af

Browse files
fix: prevent false circular-reference errors on external $ref schemas (#179)
1 parent ca82ed2 commit dc7a4af

3 files changed

Lines changed: 755 additions & 9 deletions

File tree

jsonschema/oas3/resolution.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,22 @@ func (s *JSONSchema[Referenceable]) resolve(ctx context.Context, opts references
304304
localBaseURI = jsID
305305
}
306306
}
307-
// Get the ref to build absolute reference with fragment
308-
jsRef := js.GetRef()
309-
absRef := utils.BuildAbsoluteReference(localBaseURI, string(jsRef.GetJSONPointer()))
310-
js.referenceResolutionCache = &references.ResolveResult[JSONSchemaReferenceable]{
311-
AbsoluteDocumentPath: localBaseURI,
312-
AbsoluteReference: references.Reference(absRef),
313-
ResolvedDocument: result.ResolvedDocument,
307+
308+
// Only pre-populate the cache if it hasn't already been fully resolved.
309+
// A nested ref may already have a complete resolution from a previous walk
310+
// (e.g., when multiple references point to the same external document).
311+
// Overwriting a correct cache with a pre-populated one causes false circular
312+
// reference detection because the pre-populated AbsoluteReference uses the
313+
// parent document path rather than the resolved child path.
314+
if js.referenceResolutionCache == nil || js.referenceResolutionCache.Object == nil {
315+
// Get the ref to build absolute reference with fragment
316+
jsRef := js.GetRef()
317+
absRef := utils.BuildAbsoluteReference(localBaseURI, string(jsRef.GetJSONPointer()))
318+
js.referenceResolutionCache = &references.ResolveResult[JSONSchemaReferenceable]{
319+
AbsoluteDocumentPath: localBaseURI,
320+
AbsoluteReference: references.Reference(absRef),
321+
ResolvedDocument: result.ResolvedDocument,
322+
}
314323
}
315324

316325
// Collect this reference for setting parent links after the walk

0 commit comments

Comments
 (0)