Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule no-invalid-media-type-examples check fails on example with combination of two anyOf objects #1658

Open
rsams-tw opened this issue Aug 9, 2024 · 7 comments
Labels
JSON Schema question Further information is requested Type: Bug Something isn't working

Comments

@rsams-tw
Copy link

rsams-tw commented Aug 9, 2024

Describe the bug

Given a request body specification consisting of an anyOf of two objects, it is expected that a merged object consisting of the fields of both objects should be valid. However, the no-invalid-media-type-examples rule fails when given an example with such a merged object.

To Reproduce

This is the full ruleset we use, applied to a simplified version of our specification.

redocly.yaml

extends:
  - recommended
rules:
  no-invalid-media-type-examples:
    severity: error
    allowAdditionalProperties: false
  no-invalid-parameter-examples:
    severity: error
    allowAdditionalProperties: false
  component-name-unique:
    severity: error
    schemas: error
    parameters: on
    responses: error
    requestBodies: error
  rule/get-should-not-define-requestBody:
    severity: warn
    message: '"GET" SHOULD NOT define a "requestBody" schema'
    subject:
      type: Operation
      filterInParentKeys:
        - get
    assertions:
      disallowed:
        - requestBody

spec.yml

openapi: 3.1.0
info:
  title: My API
  version: v1
  contact:
    name: Me
    url: https://www.my-domain.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
servers:
  - url: https://www.my-domain.com/api/v1
paths:
  /request:
    post:
      operationId: send-post-request
      summary: send post request
      requestBody:
        content:
          application/json:
            schema:
              type: object
              anyOf:
                - type: object
                  properties:
                    attrOne:
                      type: string
                - type: object
                  properties:
                    attrTwo:
                      type: string
            examples: 
              Example 1 - attrOne - valid:
                value:
                  attrOne: value1
              Example 2 - attrTwo - valid:
                value:
                  attrTwo: value2
              Example 3 - attrOne and attrTwo - invalid:
                value:
                  attrOne: value1
                  attrTwo: value2
components:
  securitySchemes:
    basic_auth:
      type: http
      scheme: basic
security:
  - basic_auth: []

When running redocly lint spec.yml --config redocly.yaml, the validation fails:

[1] spec.yml:42:19 at #/paths/~1request/post/requestBody/content/application~1json/examples/Example 3 - attrOne and attrTwo - invalid/value/attrTwo

Example value must conform to the schema: must NOT have unevaluated properties `attrTwo`.

40 |                 value:
41 |                   attrOne: value1
42 |                   attrTwo: value2
43 | components:
44 |   securitySchemes:

referenced from spec.yml:21:13 at #/paths/~1request/post/requestBody/content/application~1json 

Error was generated by the no-invalid-media-type-examples rule.


[2] spec.yml:41:19 at #/paths/~1request/post/requestBody/content/application~1json/examples/Example 3 - attrOne and attrTwo - invalid/value/attrOne

Example value must conform to the schema: must NOT have unevaluated properties `attrOne`.

39 |               Example 3 - attrOne and attrTwo - invalid:
40 |                 value:
41 |                   attrOne: value1
42 |                   attrTwo: value2
43 | components:

referenced from spec.yml:21:13 at #/paths/~1request/post/requestBody/content/application~1json 

Error was generated by the no-invalid-media-type-examples rule.


[3] spec.yml:41:19 at #/paths/~1request/post/requestBody/content/application~1json/examples/Example 3 - attrOne and attrTwo - invalid/value

Example value must conform to the schema: must match a schema in anyOf.

39 |               Example 3 - attrOne and attrTwo - invalid:
40 |                 value:
41 |                   attrOne: value1
42 |                   attrTwo: value2
43 | components:
44 |   securitySchemes:

referenced from spec.yml:21:13 at #/paths/~1request/post/requestBody/content/application~1json 

Error was generated by the no-invalid-media-type-examples rule.

Expected behavior

Example 3 (combination of the two anyOf options) should be considered valid by the linter.

Redocly Version(s)

1.19.0

Node.js Version(s)

22.4.0

@rsams-tw rsams-tw added the Type: Bug Something isn't working label Aug 9, 2024
@jeremyfiel
Copy link
Contributor

This configuration is overriding the schema constraints.

 no-invalid-parameter-examples:
    severity: error
    allowAdditionalProperties: false

set it to true and it will work per the schema. This was a design decision by the tooling to enforce additionalProperties: false by default.

@rsams-tw
Copy link
Author

rsams-tw commented Aug 12, 2024

This seems like a workaround, neither property is "additional" in this specification and the intent is to explicitly allow only these properties in any combination.

@jeremyfiel
Copy link
Contributor

This is not a workaround, this is changing the default behavior of a decision made by the tooling vendor to override the JSON Schema default behavior. You need to explicitly set the tooling to follow the JSON Schema rather than their own behavior.

@ipletnjov-tw
Copy link

Hey @jeremyfiel
Just to make sure I understand: allowAdditionalProperties: false forces Redocly CLI to not use JSON Schema, which (as a side-effect) bypasses the desired anyOf behavior that JSON Schema defines (https://json-schema.org/understanding-json-schema/reference/combining).
Setting this property to true forces the Redocly CLI to start strictly following the capabilities defined by JSON Schema (including anyOf).

Is that right?

@jeremyfiel
Copy link
Contributor

jeremyfiel commented Aug 13, 2024

@ipletnjov-tw the only behavior modified is the use of additionalProperties but that has an impact on other JSON Schema keywords and affects their behavior too.

To clarify, Redocly does not "turn off" the use of JSON Schema,

@tatomyr
Copy link
Contributor

tatomyr commented Aug 30, 2024

@jeremyfiel in this case it should be no-invalid-media-type-examples instead of no-invalid-parameter-examples, I believe.

@ipletnjov-tw in your case you can also switch to the default JSON Schema behaviour by explicitly adding additionalProperties: true inside each schema inside anyOf. This will have similar effect as setting allowAdditionalProperties: true but only for that local schema. However, the default JSON Schema behaviour doesn't make too much sense since it will allow literally any object including object with properties attrOne and attrTwo being numbers, booleans etc. because each of those could be any object (e.g., {attrOne: 42} is valid against the second schema in anyOf in your example), so proper validation becomes almost impossible. That's why adding additionalProperties: true explicitly is better as it doesn't impact validation of other schemas.

@tatomyr
Copy link
Contributor

tatomyr commented Sep 17, 2024

Not sure why anyOf doesn't work the same way as allOf does though. It should use unevaluatedProperties along the way and should be resolved correctly (see this issue for more context). We have to check this.

Actually, I think anyOf works a bit differently. From what I understand from the spec, it doesn't allow attrOne and attrTwo simultaneously if you set unevaluatedProperties: false on the top of the object (Redocly CLI does this by defalut). It's similar to oneOf except it doesn't allow overlapping. So the Example 3 is indeed invalid unless I'm missing something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JSON Schema question Further information is requested Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants