Skip to content

Paths are not reported correctly after multiple recursions of resolution #2043

@hudlow

Description

@hudlow

Describe the bug

It appears that the path of an error is reported correctly if resolve goes through a single $ref resolution, but not if it goes through more than one.

To Reproduce

Given this set of schemas:

Example grandparent, parent, and child schemas
openapi: 3.0.3
components:
  schemas:
    Grandparent:
      type: object
      description: Grandparent resource
      properties:
        child:
          $ref: '#/components/schemas/Parent'
    Parent:
      type: object
      description: Parent resource
      properties:
        child:
          $ref: '#/components/schemas/Child'
    Child:
      type: object
      properties:
        name:
          type: string
          description: Name for a child

...only the Child schema violates this rule:

rules:
  object-schema-description-defined:
    description: Object schemas must have a description
    severity: error
    formats: [oas3]
    given: $.components.schemas..[?(@.type == 'object')]
    then:
      field: description
      function: truthy

...but Spectral reports a violation in redundant locations:

$ spectral lint dedup.yaml

/experiments/dedup.yaml
 14:15  error  object-schema-description-defined  Object schemas must have a description  components.schemas.Parent.properties.child
 16:11  error  object-schema-description-defined  Object schemas must have a description  components.schemas.Child

✖ 2 problems (2 errors, 0 warnings, 0 infos, 0 hints)

This doesn't happen if the Grandparent schema doesn't exist, so it seems to be an artifact of Spectral looking "through" the Grandparent schema. The result makes sense to me in that if components.schemas.Parent.properties.child is "resolved" then it's the location of a second error.

But things get even stranger if I add a GreatGrandparent:

Example schemas with great grandparent
openapi: 3.0.3
components:
  schemas:
    GreatGrandparent:
      type: object
      description: Great grandparent resource
      properties:
        child:
          $ref: '#/components/schemas/Grandparent'
    Grandparent:
      type: object
      description: Grandparent resource
      properties:
        child:
          $ref: '#/components/schemas/Parent'
    Parent:
      type: object
      description: Parent resource
      properties:
        child:
          $ref: '#/components/schemas/Child'
    Child:
      type: object
      properties:
        name:
          type: string
          description: Name for a child

Now the same Spectral rule reports three errors:

$ spectral lint dedup.yaml

/experiments/dedup.yaml
 14:15  error  object-schema-description-defined  Object schemas must have a description  components.schemas.Grandparent.properties.child
 20:15  error  object-schema-description-defined  Object schemas must have a description  components.schemas.Parent.properties.child
 22:11  error  object-schema-description-defined  Object schemas must have a description  components.schemas.Child

✖ 3 problems (3 errors, 0 warnings, 0 infos, 0 hints)

The error at components.schemas.Grandparent.properties.child seems to exist because of the presence of the GreatGrandparent schema, but it doesn't really make sense to me at all, because even if one fully "resolved" the schema, there wouldn't be an error at that location. Rather, there would be one at "components.schemas.Grandparent.properties.child.properties.child", I think.

In any case, it seems like Spectral isn't able to keep track of the "real" path of an error as it recurses through a resolved document.

Expected behavior

Any number of errors caused by the same problem in the same place should report the same path.

Environment (remove any that are not applicable):

  • Library version: spectral --version reports 6.2.0
  • OS: macOS 12.1 Monterey

Metadata

Metadata

Assignees

No one assigned

    Labels

    json-refseverything JSON Refs resolving relatedreleasedt/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions