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

oneOf with discriminator does not verify json correctly #1087

Closed
seveneves opened this issue Jul 5, 2024 · 4 comments
Closed

oneOf with discriminator does not verify json correctly #1087

seveneves opened this issue Jul 5, 2024 · 4 comments

Comments

@seveneves
Copy link

Given this schema to highlight the problem

$id: resource:/schema/issueXXX
$defs:
  TypeA:
    type: object
    required:
      - kind
    properties:
      kind:
        type: string
  TypeB:
    type: object
    required:
      - kind
    properties:
      kind:
        type: string
oneOf:
  - $ref: "#/$defs/TypeA"
  - $ref: "#/$defs/TypeB"
discriminator:
  propertyName: kind
  mapping:
    A: "#/$defs/TypeA"
    B: "#/$defs/TypeB"

TypeA and TypeB are essentially the same with the difference that there is discriminator kind is registered with given mapping A and B.

Then following json cannot be validated

{"kind": "A"}

Validator provides this error

must be valid to one and only one schema, but 2 are valid with indexes '0, 1'

@justin-tay
Copy link
Contributor

The behavior looks correct to me as the discriminator doesn't affect the validation outcome of oneOf.

@seveneves
Copy link
Author

seveneves commented Jul 5, 2024

@justin-tay

Thanks for looking into this.

I don't entirely agree that it shouldn't affect the validation. It should assist with validation and indicate which Ref to use for validation. Here are statements from the specification that, in my view, confirm this:

When used, the discriminator indicates the name of the property that hints which schema definition is expected to validate the structure of the model.

A discriminator object gives a hint about the expected schema of the document. It can be used to aid in serialization, deserialization, and validation.

In the example I posted, both types TypeA and TypeB successfully validate a JSON of {"kind": "XXX"}, and when used within oneOf, the validation will fail with must be valid to one and only one schema, but 2 are valid. In this case, the discriminator hint should be used to narrow down the matching schema to the correct type. Therefore, {"kind": "A"} should hint to use the schema TypeA for validation and reject validation with TypeB.

If this isn't happening, successful validation can only be achieved when the oneOf schemas are not subsets, meaning they define required but different fields compared to each other. oneOf can also be fixed by adding validation on the discriminator field, such as enum: [A], to indicate that the discriminator value can only hold a single value for a given type. However, this just duplicates the values already defined in the mapping and results in redundant information.

@justin-tay
Copy link
Contributor

From the spec clarifications it doesn't appear that what you are asking for is compliant with the spec.

If you look at the current wording in https://github.com/OAI/OpenAPI-Specification/blob/v3.1.1-dev/versions/3.1.1.md it says

Note that discriminator MUST NOT change the validation outcome of the schema

You can ask in https://github.com/OAI/OpenAPI-Specification/issues if you think my interpretation is incorrect.

@seveneves
Copy link
Author

@justin-tay

Found this discussion which seems to confirm that oneOf is behaving correctly in this case. I guess the solution is to force addition of enum for example to each discriminator. Will do just that.

Thanks for taking time to respond!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants