stoplightio / spectral

A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v3.1, v3.0, and v2.0 as well as AsyncAPI v2.x.
https://stoplight.io/spectral
Apache License 2.0
2.37k stars 228 forks source link

Double external ref to external ref to recursive schema causes false "ref does not exist" (OAS) #2543

Open FeepingCreature opened 9 months ago

FeepingCreature commented 9 months ago

Describe the bug

When linting two schemas that both reference a schema in another file, which references a recursive schema in another file, a false "ref does not exist" error is generated.

To Reproduce

  1. Create rules.yml
extends:
  - [spectral:oas, recommended]
rules:
  info-contact: off
  oas3-api-servers: off
  operation-description: off
  1. Create foo.yml
    openapi: 3.0.0
    info:
    version: 1.0.0
    title: foo
    description: foo
    paths:
    /:
    get:
      tags:
        - Foo
      operationId: foo
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                items:
                  $ref: "proxy.yml#/components/schemas/Proxy"
    tags:
    - name: Foo
  2. Create bar.yml
    openapi: 3.0.0
    info:
    version: 1.0.0
    title: bar
    description: bar
    paths:
    /:
    get:
      tags:
        - Bar
      operationId: bar
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                items:
                  $ref: "proxy.yml#/components/schemas/Proxy"
    tags:
    - name: Bar
  3. Create proxy.yml
    components:
    schemas:
    Proxy:
      properties:
        recursive:
          $ref: "recursive.yml#/components/schemas/Recursive"
  4. Create recursive.yml
    components:
    schemas:
    Recursive:
      properties:
        next:
          $ref: "#/components/schemas/Recursive"
  5. spectral lint --ruleset rules.yml foo.yml bar.yml
    foo.yml
    1:1  error  invalid-ref  '#/components/schemas/Recursive' does not exist  components.schemas.Proxy.properties.recursive.properties.next.$ref

Expected behavior No error is produced.

Environment (remove any that are not applicable):

Additional context Only linting a single schema, foo.yml or bar.yml at a time, makes the error disappear. Inlining any ref or moving it into another file, makes the error disappear.