- changed title to Validation Loop error occurred when using allOf used
Validation Loop error occurred when allOf used with discriminator
Hello,
I’ve been implementing request validation by using OpenApiInteractionValidator
for a schema with inheritance. I’m using allOf key word with discriminator but getting the following error:
{
"errorMessage": "[Path '/content/0/basket/fruits/0'] Validation loop: schema "#/components/schemas/Apple" visited twice for pointer "/content/0/basket/fruits/0" of validated instance",
"errorCode": "validation.request.body.schema.processingError"
}
I tried to find an answer and applied all suggestions especially in FAQ and in issues. I also tried with pet.yaml file, applying with post, but still getting same error.
Example yaml for the case:
/basket:
post:
summary: Create a basket, and optionally put some fruit into it.
operationId: createBasket
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BasketResource'
responses:
'201':
description: Basket has been created, and all initial fruits were successfully given
content:
application/json:
schema:
$ref: '#/components/schemas/BasketResult'
components:
schemas:
BasketResource:
type: object
required:
- fruits
properties:
fruits:
$ref: '#/components/schemas/FruitResource'
FruitResource:
type: object
required:
- fruits
properties:
rewards:
type: array
items:
$ref: '#/components/schemas/Fruit'
Fruit:
type: object
required:
- fruitType
properties:
rewardType:
type: string
enum:
- APPLE
- ORANGE
discriminator:
propertyName: fruitType
mapping:
APPLE: AppleResource
ORANGE: OrangeResource
Apple:
allOf:
- $ref: '#/components/schemas/Fruit'
- type: object
properties:
colour:
type: string
variety:
type: string
required:
- colour
- variety
Orange:
allOf:
- $ref: '#/components/schemas/Fruit'
- type: object
properties:
originCountry:
type: string
required:
- originCountry
Version used:
swagger-request-validator-core
version: 2.8.3
Validator creation:OpenApiInteractionValidator.createFor(s).withLevelResolver(LevelResolverFactory.withAdditionalPropertiesIgnored()).build();
Hope this is simple enough explanation. Please ask for further info if needed.
Comments (26)
-
reporter -
reporter - edited description
-
Account Deactivated We faced also this issue. Also the mapper does not work really.
We use spring-boot 2 and also
swagger-request-validator-springmvc
version 2.9.0 -
Also in the latest version. Very annoying problem. Could this be solved quickly?
-
This is my case and it;s because of the mapping:
Parent: required: - childId type: object properties: childId: type: string enum: - test example: "test" discriminator: propertyName: childId mapping: test: "#/components/schemas/Test Test: description: "Just a child of Parent." allOf: - $ref: "#/components/schemas/Parent" Because mapping is pointing to Test it complains.
-
You can ignore this error by setting:
.withRule(
"see issue https://bitbucket.org/atlassian/swagger-request-validator/issues/269/validation-loop-error-occurred-when-using",
allOf(
messageHasKey("validation.request.body.schema.processingError"),
messageContains("Validation loop: schema")
))) -
reporter Hello Amon,
Yes it is easy to ignore this error by implementing the setting you shared, but we’ve just realised ignoring it actually causes a problem. By considering the first example I’d given when I opened this ticket (basket with/without fruits)
- I send a basket with fruits, all valid (all required fields exist etc). I could see the validation loop exception but the flow continues since I ignore it. So that’s OK.
- I send an invalid basket with an orange (
originCountry
is missing), I do not get a proper validation error as I do expect. There is no validation for the fields takes place. The worst is, If you didn’t implement any null check or so since you think you filter the request and validate them, unfortunately you’re wrong. You’ll get NPE in your flow.
-
reporter - changed title to Validation Loop error occurred when allOf used with discriminator
-
- attached swagger.zip
Sample project with the problem.
-
Hi,
@James Navin when do you plan to release new version with this issue fixed?
I have attached a sample project above. I have downloaded 286-269-discriminator-improvements and compiled the library and attach to my project, but I still got the loop validation error when sending following POST:
{ "vehicles": [ { "type": "Car", "power": 100, "make": "mitsubishi" }, { "type": "Train", "power": 10000, "cars": 100 }, { "type": "Plane", "power": 1000, "manufacturer": "boeing" } ] }
It is the same with or without discriminator mapping.
Please give me some feedback, as it blocks our project
Regards
-
Hi Przemek,
I'm planning to release a version with the changes from that branch soon - I'm just waiting to land a couple of other PRs first. I can’t commit to a date yet, but within the next week or so.
Thanks for attaching the sample - I’ll test it against that branch and hopefully be able to get a fix for it.
Cheers,
James
-
@James Navin Any news on this?
-
@James Navin Hi James
I get same error as below
Caused by: com.atlassian.oai.validator.restassured.OpenApiValidationFilter$OpenApiValidationException: { "messages" : [ { "key" : "validation.response.body.schema.processingError", "level" : "ERROR", "message" : "[Path '/contentSlots/0/components/0'] Validation loop: schema \"#/components/schemas/CMSParagraphComponent\" visited twice for pointer \"/contentSlots/0/components/0\" of validated instance", "context" : { "requestPath" : "/v1/cms/pages", "responseStatus" : 200, "location" : "RESPONSE", "requestMethod" : "GET" } } ] }
It will be of great help if you can get your fix merged. Thanks so much
-
@Przemek Brzosko I finally got some time to look at your specific case. Its interesting and a little challenging to solve in the current implementation :)
The validation loop error is coming out of the underlying schema validation library - it maintains a validation stack to detect loops so you don’t enter an infinite cycle. The problem with the way the
allOf
+discriminator
works is that it needs a validation loop by design [parent type (initial ref) → sub type (discriminator ref) → parent type (allOf include) ]. The validator works in that scenario because I can control the stack within thediscriminator
validation, but in your case there is the additional layer of [sub type (oneOf ref) → parent type (allOf ref) → sub type (discriminator ref) → parent type (allOf ref)] which triggers the loop.Ptr URI Validator "" /vehicles #/components/schemas/Data/properties/vehicles InstanceValidator /vehicles #/components/schemas/Data/properties/vehicles/items InstanceValidator /vehicles/0 #/components/schemas/Data/properties/vehicles/items/oneOf/0 OneOfValidator /vehicles/0 #/components/schemas/Car/allOf/0 AllOfValidator /vehicles/0 #/components/schemas/Car Discriminator /vehicles/0 #/components/schemas/Car/allOf/0 Discriminator One thing I will look at is short-circuiting the
discriminator
validation if the starting point is the sub-type (e.g. inspect the stack and see if the sub-type has already been visited).Thanks for providing the test case!
-
- changed status to open
-
@James Navin
Hi James thanks so much for taking up the issue. I know you did say its going to take time as its a complicated issue.
Just wanted to check if there are any branches we can try to help you with some testing, if issue fixed.
-
Hi, do we have a fix for this issue ?
-
Solutions is already given above to ignore this error.
return com.atlassian.oai.validator.whitelist.ValidationErrorsWhitelist.create() .withRule("<put description>", allOf( methodIs(HttpMethod.<put here GET/POST/??>), pathContainsSubstring("<put URI>"), messageHasKey("validation.request.body.schema.processingError"), messageContains("Validation loop: schema") ))
-
Hi Abhay, The solution of whitelisting does not work as mentioned by Kübra Zeray in above thread.
-
Hi all,
A colleague has done some work on this and come up with a fix. The repro test case is now green.
Fix is available in
v2.25.0
I’ll mark this issue as resolved, but if you still encounter the problem please re-open with an example to reproduce and we will look at it again.
Thanks for the patience.
James
-
- changed status to resolved
-
@James Navin
Hi James,
I have the below schema which gives me
"Validation loop: schema "#/components/schemas/Car/_discriminatorValidation" visited twice for pointer "" of validated instance"
error upon validation withv2.25.0
of my response in case of a even a very basic Car like{"id":0,"name":null,"type":"car","luxury":false}
.I am new to Open API so it can easily happen that my schema uses the discriminator incorrectly, however my understanding on the Open API documentation is that it can be used this way.
I would really appreciate some expert opinion.
Thanks,
Tamas
openapi: 3.0.1 info: title: REST API version: v1 paths: "/vehicle": get: tags: - Vehicles operationId: getVehicle responses: '200': description: Success|OK content: "*/*": schema: oneOf: - "$ref": "#/components/schemas/Car" - "$ref": "#/components/schemas/Plane" components: schemas: Plane: type: object allOf: - "$ref": "#/components/schemas/Vehicle" - type: object properties: manufacturer: type: string Car: type: object allOf: - "$ref": "#/components/schemas/Vehicle" - type: object properties: isLuxury: type: boolean Vehicle: required: - type type: object properties: id: type: integer format: int64 name: type: string type: type: string enum: - car - plane discriminator: propertyName: type mapping: car: "#/components/schemas/Car" plane: "#/components/schemas/Plane"
-
Hi Tamas,
Can you please try with the latest version of the library. There were further improvements added to address this problem in v2.25.1.
Please let me know if you still experience problems with the latest version (2.27.0)
Thanks,
James
-
@James Navin With both
v2.25.1
andv2.27.0
the validation hangs for a while then ends with anOutOfMemoryError
with below stack trace. I increased the the heap size up to 8GB to see where it goes but that did not solve anything.java.lang.OutOfMemoryError: Java heap space at java.base/java.util.LinkedHashMap.newNode(LinkedHashMap.java:256) at java.base/java.util.HashMap.putVal(HashMap.java:627) at java.base/java.util.HashMap.put(HashMap.java:608) at com.fasterxml.jackson.databind.node.ObjectNode.deepCopy(ObjectNode.java:57) at com.fasterxml.jackson.databind.node.ObjectNode.deepCopy(ObjectNode.java:19) .... at com.fasterxml.jackson.databind.node.ObjectNode.deepCopy(ObjectNode.java:57) at com.fasterxml.jackson.databind.node.ObjectNode.deepCopy(ObjectNode.java:19) at com.fasterxml.jackson.databind.node.ObjectNode.deepCopy(ObjectNode.java:57) at com.atlassian.oai.validator.schema.keyword.DiscriminatorKeywordValidator.validateAllOfComposition(DiscriminatorKeywordValidator.java:206) at com.atlassian.oai.validator.schema.keyword.DiscriminatorKeywordValidator.doValidate(DiscriminatorKeywordValidator.java:101)
Thanks,
Tamas
-
Thanks for reporting. I’ll raise a separate ticket to track this bug. At first glance it looks like our approach to tracking the validation stack is failing for your case.
-
Raised #380
- Log in to comment