Skip to content

Unresolved references not throwing an error in v2 #2558

Description

Describe the bug
One of our integration tests seem to have flagged a regression from v1 to v2. This seems to have been tackled a couple of times, first in #1470, resolved by #1503. It then looks like Warnings were noticed to be gone and added back by #2459.

The test from #1503 still passes, but it looks like the errors is not added if the reference lives in the path (I didn't dig deeper yet).

OpenApi File To Reproduce

openapi: 3.0.3
info:
  title: UserAPI
  version: '1.0'
  description: The User API
servers:
  - url: 'http://localhost:3000'
paths:
  '/v1/users/{userId}':
    parameters:
      - $ref: '#/components/parameters/userId'
    get:
      summary: Get User Info by User ID
      tags:
        - users
      responses:
        '200':
          description: User Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/user'
      description: Retrieve the information of the user with the matching user ID.
components:
  schemas:
    User:
      title: User
      type: object
      description: ''
      properties:
        id:
          type: integer
          description: Unique identifier for the given user.
        firstName:
          type: string
        lastName:
          type: string
      required:
        - id
        - firstName
        - lastName
  parameters:
    userId:
      name: userId
      in: path
      required: true
      schema:
        type: string
      description: the id of an existing user
tags:
  - name: users

Expected behavior
Since #1503 has an explicit test case containing the error I am looking for, I am assuming it is intended for there to be a "Invalid reference" error with the above file, rather than just a warning.

Screenshots/Code Snippets
Example test snippet for v1 (passes)

[Fact]
public async Task Validate_ThrowsReferenceDoesntExist_Error()
{
    // Arrange
    var input = 
    """
[...snip, use the above example...]
    """;
    var reader = new OpenApiStreamReader();
    await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));

    // Act
    var result = await reader.ReadAsync(stream);

    // Assert
    (result.OpenApiDiagnostic != null && result.OpenApiDiagnostic.Errors.Any()).Should().BeTrue();
    result.OpenApiDiagnostic.Errors.Should().BeEquivalentTo(new List<OpenApiError>
    {
        new(new OpenApiException("Invalid Reference identifier 'user'."))
    });
}

The v2 equivalent:

[Fact]
public async Task Validate_ThrowsReferenceDoesntExist_Error()
{
    // Arrange
    var input =
    """
[...snip, use the above example...]
    """;
    var settings = new OpenApiReaderSettings();
    settings.AddYamlReader();
    await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));

    // Act
    var result = await OpenApiDocument.LoadAsync(stream, null, settings, CancellationToken.None);

    // Assert
    (result.Diagnostic != null && result.Diagnostic.Errors.Any()).Should().BeTrue();
    result.Diagnostic.Errors.Should().BeEquivalentTo(new List<OpenApiError>
    {
        new(new OpenApiException("Invalid Reference identifier 'user'."))
    });
}

result.Diagnostic.Errors is empty, though the warning about the non-existent reference is there.

Activity

  1. crudbee commented on Oct 22, 2025

    @crudbee
    Author

    The test expectation in test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs#DiagnosticReportMergedForExternalReferenceAsync was removed in #1955, and I must admit, I don't think I immediately see why. Is the lack of error actually intentional?

    e: Nope, got it, the previously tested for error was about empty paths, my bug is specifically about what seems to be a change of behaviour on a slightly different setup.

  2. baywet commented on Jan 19, 2026

    @baywet
    Member

    Hey everyone!
    Thank you for using the SDK and for reaching out.
    Thank you for your patience.

    Somehow I had missed this issue...
    This is by design because of the revamp of how references work, lazy loading, the workspace system, etc...

    However, there was clearly a documentation gap on this aspect, so I put together #2692

    In addition, I updated hidi to log warnings as well during validation, #2691

    Let me know if you have any additional comments or questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

type:documentationGeneral documentation request or project documentation update

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions