Repository navigation
Validation issue #28
Copy link
Copy link
Closed
Description
Hey @VisualBean,
I think i found issue with validation, my schema looks like that:
{
"asyncapi": "3.1.0",
"info": {
"title": "Test API",
"version": "1.0.0",
"description": "Test API for integration tests"
},
"id": "urn:asyncapi",
"servers": {
"test-server": {
"host": "localhost:5000",
"protocol": "http"
},
"smtp-server": {
"host": "localhost:25",
"protocol": "smtp"
},
"websocket-server": {
"host": "localhost:8080",
"protocol": "ws"
}
},
"channels": {
"orderscreated": {
"address": "orders/created",
"messages": {
"orderCreatedEvent": {
"$ref": "#/components/messages/orderCreatedEvent"
}
},
"description": "Channel for order creation events"
},
"orderscancelled": {
"address": "orders/cancelled",
"messages": {
"orderCancelledEvent": {
"$ref": "#/components/messages/orderCancelledEvent"
}
},
"description": "Channel for order cancellation events"
},
"paymentsprocessed": {
"address": "payments/processed",
"messages": {
"paymentProcessedEvent": {
"$ref": "#/components/messages/paymentProcessedEvent"
}
},
"description": "Channel for payment events"
},
"notificationsemail": {
"address": "notifications/email",
"messages": {
"emailNotification": {
"$ref": "#/components/messages/emailNotification"
}
},
"description": "Email notification channel",
"servers": [
{
"$ref": "#/servers/smtp-server"
}
]
},
"notificationspush": {
"address": "notifications/push",
"messages": {
"pushNotification": {
"$ref": "#/components/messages/pushNotification"
}
},
"description": "Push notification channel",
"servers": [
{
"$ref": "#/servers/websocket-server"
}
]
},
"usersuserIdevents": {
"address": "users/{userId}/events",
"messages": {
"userUpdatedEvent": {
"$ref": "#/components/messages/userUpdatedEvent"
}
},
"description": "User-specific events channel",
"parameters": {
"userId": {
"description": "The user identifier"
}
}
},
"inventoryupdates": {
"address": "inventory/updates",
"messages": {
"inventoryUpdatedEvent": {
"$ref": "#/components/messages/inventoryUpdatedEvent"
}
},
"description": "Inventory update events"
},
"auditevents": {
"address": "audit/events",
"messages": {
"auditLoginEvent": {
"$ref": "#/components/messages/auditLoginEvent"
},
"auditLogoutEvent": {
"$ref": "#/components/messages/auditLogoutEvent"
},
"auditActionEvent": {
"$ref": "#/components/messages/auditActionEvent"
}
},
"description": "Audit event channel"
}
},
"operations": {
"OrderEventHandler_HandleOrderCreated_Subscribe": {
"action": "send",
"channel": {
"$ref": "#/channels/orderscreated"
},
"title": "OrderEventHandler_HandleOrderCreated_Subscribe",
"summary": "Subscribe to order creation events",
"messages": [
{
"$ref": "#/channels/orderscreated/messages/orderCreatedEvent"
}
]
},
"OrderEventHandler_HandleOrderCancelled_Subscribe": {
"action": "send",
"channel": {
"$ref": "#/channels/orderscancelled"
},
"title": "OrderEventHandler_HandleOrderCancelled_Subscribe",
"summary": "Subscribe to order cancellation events",
"messages": [
{
"$ref": "#/channels/orderscancelled/messages/orderCancelledEvent"
}
]
},
"OrderEventPublisher_PublishOrderCreated_Publish": {
"action": "receive",
"channel": {
"$ref": "#/channels/orderscreated"
},
"title": "OrderEventPublisher_PublishOrderCreated_Publish",
"summary": "Publish order creation events",
"messages": [
{
"$ref": "#/channels/orderscreated/messages/orderCreatedEvent"
}
]
},
"handlePaymentProcessed": {
"action": "send",
"channel": {
"$ref": "#/channels/paymentsprocessed"
},
"title": "handlePaymentProcessed",
"summary": "Handle payment processed events",
"messages": [
{
"$ref": "#/channels/paymentsprocessed/messages/paymentProcessedEvent"
}
]
},
"MultiServerHandler_SendEmailNotification_Publish": {
"action": "receive",
"channel": {
"$ref": "#/channels/notificationsemail"
},
"title": "MultiServerHandler_SendEmailNotification_Publish",
"summary": "Send email notifications",
"messages": [
{
"$ref": "#/channels/notificationsemail/messages/emailNotification"
}
]
},
"MultiServerHandler_SendPushNotification_Publish": {
"action": "receive",
"channel": {
"$ref": "#/channels/notificationspush"
},
"title": "MultiServerHandler_SendPushNotification_Publish",
"summary": "Send push notifications",
"messages": [
{
"$ref": "#/channels/notificationspush/messages/pushNotification"
}
]
},
"handleUserEvent": {
"action": "send",
"channel": {
"$ref": "#/channels/usersuserIdevents"
},
"title": "handleUserEvent",
"summary": "Handle user-specific events",
"messages": [
{
"$ref": "#/channels/usersuserIdevents/messages/userUpdatedEvent"
}
]
},
"IInventoryEventHandler_HandleInventoryUpdate_Subscribe": {
"action": "send",
"channel": {
"$ref": "#/channels/inventoryupdates"
},
"title": "IInventoryEventHandler_HandleInventoryUpdate_Subscribe",
"summary": "Handle inventory updates",
"messages": [
{
"$ref": "#/channels/inventoryupdates/messages/inventoryUpdatedEvent"
}
]
},
"handleAuditEvents": {
"action": "send",
"channel": {
"$ref": "#/channels/auditevents"
},
"title": "handleAuditEvents",
"summary": "Handle all audit events",
"messages": [
{
"$ref": "#/channels/auditevents/messages/auditLoginEvent"
},
{
"$ref": "#/channels/auditevents/messages/auditLogoutEvent"
},
{
"$ref": "#/channels/auditevents/messages/auditActionEvent"
}
]
}
},
"components": {
"schemas": {
"auditActionEvent": {
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"action": {
"type": "string"
},
"resource": {
"type": "string"
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"auditLoginEvent": {
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"loginTime": {
"type": "string",
"format": "date-time"
},
"ipAddress": {
"type": "string"
}
}
},
"auditLogoutEvent": {
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"logoutTime": {
"type": "string",
"format": "date-time"
}
}
},
"emailNotification": {
"type": "object",
"properties": {
"to": {
"type": "string"
},
"subject": {
"type": "string"
},
"body": {
"type": "string"
}
}
},
"inventoryUpdatedEvent": {
"type": "object",
"properties": {
"productId": {
"type": "string"
},
"previousQuantity": {
"type": "string",
"format": "int32"
},
"newQuantity": {
"type": "string",
"format": "int32"
},
"warehouseId": {
"type": "string"
}
}
},
"orderCancelledEvent": {
"type": "object",
"properties": {
"orderId": {
"type": "string",
"format": "uuid"
},
"reason": {
"type": "string"
},
"cancelledAt": {
"type": "string",
"format": "date-time"
}
}
},
"orderCreatedEvent": {
"type": "object",
"properties": {
"orderId": {
"type": "string",
"format": "uuid"
},
"customerName": {
"type": "string"
},
"totalAmount": {
"type": "string",
"format": "double"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"productName": {
"type": "string"
},
"quantity": {
"type": "string",
"format": "int32"
},
"unitPrice": {
"type": "string",
"format": "double"
}
}
}
}
}
},
"paymentProcessedEvent": {
"type": "object",
"properties": {
"paymentId": {
"type": "string",
"format": "uuid"
},
"orderId": {
"type": "string",
"format": "uuid"
},
"amount": {
"type": "string",
"format": "double"
},
"paymentMethod": {
"type": "string"
},
"status": {
"type": "integer"
}
}
},
"pushNotification": {
"type": "object",
"properties": {
"deviceToken": {
"type": "string"
},
"title": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"userUpdatedEvent": {
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"email": {
"type": "string"
},
"displayName": {
"type": "string"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"messages": {
"orderCreatedEvent": {
"payload": {
"$ref": "#/components/schemas/orderCreatedEvent"
},
"name": "orderCreatedEvent",
"title": "orderCreatedEvent"
},
"orderCancelledEvent": {
"payload": {
"$ref": "#/components/schemas/orderCancelledEvent"
},
"name": "orderCancelledEvent",
"title": "orderCancelledEvent"
},
"paymentProcessedEvent": {
"payload": {
"$ref": "#/components/schemas/paymentProcessedEvent"
},
"name": "paymentProcessedEvent",
"title": "paymentProcessedEvent"
},
"emailNotification": {
"payload": {
"$ref": "#/components/schemas/emailNotification"
},
"name": "emailNotification",
"title": "emailNotification"
},
"pushNotification": {
"payload": {
"$ref": "#/components/schemas/pushNotification"
},
"name": "pushNotification",
"title": "pushNotification"
},
"userUpdatedEvent": {
"payload": {
"$ref": "#/components/schemas/userUpdatedEvent"
},
"name": "userUpdatedEvent",
"title": "userUpdatedEvent"
},
"inventoryUpdatedEvent": {
"payload": {
"$ref": "#/components/schemas/inventoryUpdatedEvent"
},
"name": "inventoryUpdatedEvent",
"title": "inventoryUpdatedEvent"
},
"auditLoginEvent": {
"payload": {
"$ref": "#/components/schemas/auditLoginEvent"
},
"name": "auditLoginEvent",
"title": "auditLoginEvent"
},
"auditLogoutEvent": {
"payload": {
"$ref": "#/components/schemas/auditLogoutEvent"
},
"name": "auditLogoutEvent",
"title": "auditLogoutEvent"
},
"auditActionEvent": {
"payload": {
"$ref": "#/components/schemas/auditActionEvent"
},
"name": "auditActionEvent",
"title": "auditActionEvent"
}
}
}
}
however when i debugged validation for servers:
it seems it applied v2 validation instead of v3 because of usage
// Assert - Parse with ByteBard.AsyncAPI.NET reader to validate schema
var reader = new AsyncApiStringReader();
var document = reader.Read(content, out var diagnostic);
You can find example in this test:
https://github.com/bielu/Bielu.AspNetCore.AsyncApi/blob/a60eb5f1a0ed645137f0f831ae9f17b9ee25d257/test/Bielu.AspNetCore.AsyncApi.Tests/Integration/AsyncApiDocumentGenerationTests.cs#L135
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
VisualBean commentedon Feb 24, 2026
Im not sure I understand the issue. You are saying double parsing and v2 validation.
What is your expected outcome?
Do you have a 'minimal' repro?
Edit: I think i see it now. The diagnostics errors are wrong.
VisualBean commentedon Feb 24, 2026
TLDR;
They are parsed twice, due to the references.
There is a missing registration step in the AsyncApiWorkspace (we do similar for channels)
Add something like
below where channels are registered in
AsyncApiWorkspace(line 207)This will register them, so we don't instantiate them twice (as part of the reference resolution).
Currently we deserialize the spec, then walk the references to properly dereference them.
Most references will already have been pre-registered in the AsyncApiWorkspace, as part of the initial deserialization, but servers were missing, so they were looked up and instantiated (why they were parsed multiple times).
VisualBean commentedon Feb 25, 2026
#29 fixes this issue. closing.
bielu commentedon Feb 25, 2026
@VisualBean can ping me when you release next beta?
VisualBean commentedon Feb 25, 2026
@bielu ByteBard.AsyncAPI.NET.2.1.3-beta.14 has been released