Discriminator does not seem to be evaluated

Issue #289 new
Dennie Ackermann created an issue

Hi,

I cloned the (last week) current version of the swagger-request-validator, version 2.10.1-SNAPSHOT.
I am struggeling with validating a complex schema with nested schemas in it. The components/schemas shall be designed by/with the model of an existing complex object oriented model.
I designed the Open Api Spec by using allOf for designing inheritance/polymorphism. But I always got the error, something with 'validation loop: schema "..." visited twice for pointer "..." of validated instance'. So I designed it with the properties inline.
Now, to have a clear and complete predication of what ref's the properties are, I applied oneOf in them, when there is referenced a type, that is extended (potentially with allOf, but these are gone now as stated) somewhere and the json could also or exclusively be some extended type/schema.
My first try: Use allOf for Inheritance, apply a discriminator in the super-type and use oneOf in the references, where this supertype is referenced. -> Result was this validation loop error.
My second try: eliminate the allOfs (at least just to make it work as a start) and try it with that. -> Result was: Something with 'Instance failed to match exactly one schema (matched 3 out of 3)'.
I also tried as a third try to apply the discriminator in the oneOf's in the properties. Same result.
Now I tried to create a schema-object that cares for the oneOf and reference only that one in the property. -> Same result.

My very simplified and minimized example: (Maybe I did something wrong and I would appreciate a hint and a working example then (for testing purposes, please erase my <--comments)):

    "contractBox": {
            "title": "contractBox",
            "description": "schema using a ref to a oneOf schema",
            "type": "object",
            "properties": {
                "mycontract": {
                    "$ref": "#/components/schemas/ContractPossibilities"  <-- Here the oneOf-Reference-Schema is referenced
                }
            }
        },
        "ContractPossibilities": {  <-- The oneOf-Reference-Schema is designed
            "title": "ContractPossibilities",
            "oneOf": [
                {
                    "$ref": "#/components/schemas/Contract"
                },
                {
                    "$ref": "#/components/schemas/ContractLevel1"
                },
                {
                    "$ref": "#/components/schemas/ContractLevel2"
                }
            ],
            "discriminator": {  <-- this discriminator does not seem to be taken account of in the validator (Version 2.10.1-SNAPSHOT cloned from git)
                "propertyName": "ourSpecialType",
                "mapping": { <-- this seems to be redundant for me, but it was a try and hopefully does not make it worse till I got it.
                    "Contract": "#/components/schemas/Contract",
                    "ContractLevel1": "#/components/schemas/ContractLevel1",
                    "ContractLevel2": "#/components/schemas/ContractLevel2"
                }
            }
        },
        "Contract": {
            "title": "Contract",
            "type": "object",
            "required": [
                "ourSpecialType"
            ],
            "properties": {
                "ourSpecialType": {
                    "type": "string"
                },
                "propertyOne": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/something"
                    }
                }
            },
            "description": ""
        },
        "ContractLevel1": {
            "title": "ContractLevel1",
            "description": "",
            "type": "object",
            "required": [
                "ourSpecialType"
            ],
            "properties": {
                "ourSpecialType": {
                    "type": "string"
                },
                "propertyOne": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/something"
                    }
                },
                "propertyTwo": {
                    "$ref": "#/components/schemas/somethingElse"
                }
            }
        },
        "ContractLevel2": {
            "title": "ContractLevel2",
            "description": "",
            "type": "object",
            "required": [
                "ourSpecialType"
            ],
            "properties": {
                "ourSpecialType": {
                    "type": "string"
                },
                "propertyOne": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/something"
                    }
                },
                "propertyTwo": {
                    "$ref": "#/components/schemas/somethingElse"
                },
                "propertyThree": {
                    "$ref": "#/components/schemas/somethingCompletelyElse"
                }
            }
        }, ...

When validating a json that should be a ContractLevel1 (after our object oriented model) but does not implement the propertyTwo nor propertyThree, then the validation seems to fit all three schemas, as if the discriminator would not be there.
... Instance failed to match exactly one schema (matched 3 out of 3) ...
A workaround could be to give required properties, but there are more than these and there could be one or another and none is mandatory.
Eather I have a bug in the Spec or there is a bug in the validator.

Could you please investigate a look on it, please?

Thank you very much in advance.

Comments (3)

  1. James Navin

    Thanks for raising this.

    You are correct - what’s happening here is that the schemas are overlapping, and so if propertyThree is not provided then multiple can match and so the oneOf will fail. Ideally the validator should be using the discriminator to select between them - I will look at adding that.

    In the meantime you could try:

    1. Change oneOf to anyOf, which should then validate properly
    2. Adding an enum to the ourSpecialType schema in each of the sub-types to restrict the value to the discriminator value (this is a bit of a hack but would then make the schemas non-overlapping)

    The validation loop problem you mentioned is known - see #269. I am working on a fix for that now.

  2. Log in to comment