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), Arazzo v1.0, as well as AsyncAPI v2.x.
https://stoplight.io/spectral
Apache License 2.0
2.45k stars 235 forks source link

spectral-rulesets 1.19.0 breaks path $ref behavior #2655

Open jstuckey opened 1 month ago

jstuckey commented 1 month ago

Describe the bug

Using a $ref keyword under a path http verb started producing an error in version 1.19.0 of the spectral-rulesets package:

error  oas3-schema  Property "$ref" is not expected to be here.     paths./<some_path>.<some_verb>.$ref

This behavior is not present in spectral-rulesets 1.18.1 and earlier.

To Reproduce

  1. Given this OpenAPI document
    
    openapi: 3.0.3
    info:
    title: Foo
    version: 1.0.0
    description: Foo API
    contact:
    name: Foo
    tags:
    - name: FooTag
    servers:
    - url: https://example.com
    description: Example

paths: /foos: get: $ref: 'foo_request.yaml'


```yaml
# foo_request.yaml
description: Get a list of foos
summary: List Foos
operationId: foosIndex
tags:
  - FooTag
responses:
  "200":
    description: A collection of foos
    content:
      application/json:
        schema:
          type: object
          properties:
            foos:
              type: array
              description: The list of foos
              items:
                type: string
  1. Run this CLI command
    npx spectral lint openapi.yaml
  2. See error
    openapi.yaml
    16:9  error  oas3-schema  "get" property must have required property "responses".  paths./foos.get
    17:13  error  oas3-schema  Property "$ref" is not expected to be here.              paths./foos.get.$ref

Expected behavior

Using version 1.18.1 of the spectral-rulesets package produces the expected behavior:

No results with a severity of 'error' found!

Environment (remove any that are not applicable):

Additional context

If I had to hazard a guess, I suspect this change to be the culprit: https://github.com/stoplightio/spectral/pull/2574

jstuckey commented 1 month ago

The spec explicitly says that the path item object supports $ref while the operation object does not. I'm guessing that is why the setup I've described above is now considered invalid.

Still, the OpenAPI rendering tools I've used (Redoc, GitLab) handle this setup, and Spectral previously allowed it. It caught me off guard that our OpenAPI doc suddenly failed to lint.

afmhenry commented 4 weeks ago

Running into this issue as well. I think it is fair that $refs are resolved when determining if the contents of a schema are valid.

It makes using reusable servers, externalDocs, and other parts of OAS definitions standard and I don't want to disable that rule (as it is usually helpful :) )

I eventually bundle the OAS document, resolving these, but spectral is the initial linting tool to make sure we can bundle it all up.

afmhenry commented 3 weeks ago

https://github.com/stoplightio/spectral/commit/8df2c36d7461a86b3f6fb77fcd1759ed0c3750a0#diff-a4b02cdf70d6d4ff86a25b14f73e37f38cb47807de5ed4018c5384ed74d5a14fR682

If this was not set to "resolved": false, I believe the issue would have been avoided