Skip to content

fix: resolve external 3.x payload references - #59

Merged
VisualBean merged 4 commits into
ByteBardOrg:vnextfrom
bielu:fix/v3-external-multiformat-payload-reference
Oct 24, 2026
Merged

VisualBean merged 4 commits into
ByteBardOrg:vnextfrom
bielu:fix/v3-external-multiformat-payload-reference

Conversation

@bielu

@bielu bielu commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Found while adding 3.x tests for #56.

In 3.x, payload: $ref: ... is read as an AsyncApiMultiFormatSchemaReference. When an external reference is resolved, the Schema case only handled AsyncApiJsonSchemaReference and AsyncApiAvroSchemaReference, so nothing was read for a payload reference. Every external 3.x payload reference, with or without a fragment, failed with Unable to deserialize reference '…'. This happens on vnext today and doesn't depend on #56.

The external content is now read as a Multi Format Schema Object. That also accepts a plain Schema Object, which the spec allows as a payload.

Wrapping the reference in a multi-format object (payload: { schemaFormat, schema: { $ref } }) already worked, because that goes through the JSON-schema path.

Testing

  • Added 3 tests: a fragment pointing at a plain schema, a fragment pointing at a multi-format object, and a whole-file reference. They also check the $ref is kept when the document is written back. All 3 fail without the fix.
  • dotnet test: 405 passed on net8.0, net9.0 and net10.0.

🤖 Generated with Claude Code

@bielu
bielu requested a review from VisualBean as a code owner October 24, 2026 14:03
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 14 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a44ded83-d03f-4cce-be2f-bff393d1a2d3
Commits

Reviewing files that changed from the base of the PR and between ff96a92 and 4947bd4.

Files selected for processing: 3
  • src/ByteBard.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs
  • src/ByteBard.AsyncAPI.Readers/V2/AsyncApiV2VersionService.cs
  • test/ByteBard.AsyncAPI.Tests/Models/AsyncApiReference_Should.cs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

In 3.x a message payload reference is an AsyncApiMultiFormatSchemaReference.
Resolving an external reference only handled JSON and Avro schema
references, so an external payload such as `$ref: './payload.json'` was
never read and reported "Unable to deserialize reference". The external
content is now read as a Multi Format Schema Object, which also accepts a
plain Schema Object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bielu
bielu force-pushed the fix/v3-external-multiformat-payload-reference branch from 37032b6 to 87a19e9 Compare October 24, 2026 20:38
@VisualBean

Copy link
Copy Markdown
Contributor

Note that this doesnt solely touch external references. It also touches references where the initial pass or stored ref (in the workspace) doesnt resolve properly. We fall back to ResolveStreamReference.
It might not mean anything to this particular PR, but its an important distinction.

ResolveStreamReference is also the fallback for local references that are
not in the workspace, not only for external ones. In a 2.x document every
local payload reference is an AsyncApiMultiFormatSchemaReference, so the
fallback asked the 2.x reader for an AsyncApiMultiFormatSchema loader it
did not have and Read() threw KeyNotFoundException.

The 2.x reader now loads a Multi Format Schema by reading the payload as a
JSON Schema and wrapping it, since 2.x keeps schemaFormat on the message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bielu

bielu commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@VisualBean Good point, and it did matter here. I checked the local fallback with a payload $ref to a local location that isn't a registered component (#/components/messages/shared/payload):

  • 3.x: it now resolves to the schema, where vnext reported "Unable to deserialize reference". That's an improvement from the same change.
  • 2.x: it threw KeyNotFoundException out of Read(). The 2.x reader turns local payload references into AsyncApiMultiFormatSchemaReference, and the fallback then asked the 2.x reader for an AsyncApiMultiFormatSchema loader, which it didn't have.

Fixed in ed63267: the 2.x reader now has a Multi Format Schema loader that reads the payload as a JSON Schema and wraps it, matching how 2.x keeps schemaFormat on the message. LocalPayloadReference_NotInWorkspace_ResolvesPayload covers the fallback for both 2.6.0 and 3.0.0.

@VisualBean

Copy link
Copy Markdown
Contributor

Please add an avro version of the LocalPayloadReference_NotInWorkspace_ResolvesPayload test

Adds LocalAvroPayloadReference_NotInWorkspace_ResolvesPayload for 2.6.0
and 3.0.0, as requested in review.

The 2.x case failed. For a 2.x document, the whole-document stream that
the local fallback reads is the upgraded document serialized as 3.0, so
an Avro payload appears there as a Multi Format Schema Object
({ schemaFormat, schema }). The 2.x loader read it as a JSON Schema and
reported "schemaFormat/schema is not a valid property". The 2.x reader
now uses the 3.x Multi Format Schema loader for that fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bielu

bielu commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@VisualBean added and found bug related to it!

@VisualBean
VisualBean merged commit e816843 into ByteBardOrg:vnext Oct 24, 2026
6 checks passed
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.

2 participants