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

Unexpected behavior when validating a schema with anyOf between two objects #2500

Open
ItamarMalka opened this issue Oct 13, 2024 · 2 comments

Comments

@ItamarMalka
Copy link

What version of Ajv are you using? Does the issue happen if you use the latest version? reproduces for me on latest version

I am seeing that for some reason when having a schema with an anyof between two objects the removeAdditionalProperties does not consider all the possible keys when removing the properties from the object and only looks at the first object in the anyOf

jsfiddle with the issue reproduced:
https://jsfiddle.net/x7s85b3t/1/

Your code

const schema = {
  "properties": {
    "body": {
      "type": "object",
      "properties": {
        "configuration": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "differentA": {
                  "type": "string"
                },
                "differentB": {
                  "type": "string"
                }
              },
              "required": [
                "differentA",
                "differentB"
              ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "propA": {
                  "type": "string"
                },
                "propB": {
                  "type": "string"
                }
              },
              "required": [
                "propA",
                "propB"
              ],
              "additionalProperties": false
            }
          ]
        }
      },
      "required": [
        "configuration"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "body"
  ],
  "additionalProperties": true,
  "definitions": {}
}

var json = {
  body:  {
    "configuration": {
        "propA": "1",
        "propB": "2"
    }
    }
};
var ajv = new Ajv({
	allErrors: true,
	removeAdditional: true
});

var result = ajv.validate(schema, json);

console.log('Result: ', result);
console.log('Errors: ', ajv.errors);
console.log('Final Configuration object json: ', JSON.stringify(json.body.configuration));

Validation result, data AFTER validation, error messages

"Errors: ", [{
  dataPath: ".body.configuration",
  keyword: "required",
  message: "should have required property 'differentA'",
  params: {
    missingProperty: "differentA"
  },
  schemaPath: "#/properties/body/properties/configuration/anyOf/0/required"
}, {
  dataPath: ".body.configuration",
  keyword: "required",
  message: "should have required property 'differentB'",
  params: {
    missingProperty: "differentB"
  },
  schemaPath: "#/properties/body/properties/configuration/anyOf/0/required"
}, {
  dataPath: ".body.configuration",
  keyword: "required",
  message: "should have required property 'propA'",
  params: {
    missingProperty: "propA"
  },
  schemaPath: "#/properties/body/properties/configuration/anyOf/1/required"
}, {
  dataPath: ".body.configuration",
  keyword: "required",
  message: "should have required property 'propB'",
  params: {
    missingProperty: "propB"
  },
  schemaPath: "#/properties/body/properties/configuration/anyOf/1/required"
}, {
  dataPath: ".body.configuration",
  keyword: "anyOf",
  message: "should match some schema in anyOf",
  params: { ... },
  schemaPath: "#/properties/body/properties/configuration/anyOf"
}]
"Final Configuration object json: ", "{}"

What results did you expect?
I expected that the remove additional properties will take all the possible object keys into consideration and not only the first one, so I am able to have a schema that allows any of the objects inside the anyof where in reality it fails for the second object

@trevorparscal
Copy link

I think I bumped into the same issue today. Here's my scenario...

const a = {
	type: 'object',
	properties: {
		x: { type: 'number' }
	},
	required: [ 'x' ],
	additionalProperties: false
};

const b = {
	type: 'object',
	properties: {
		x: { type: 'number' },
		y: { type: 'number' }
	},
	required: [ 'x', 'y' ],
	additionalProperties: false
};

const any = {
	anyOf: [ a, b ]
};

Validation against any only works for objects conforming to schema a. Objects conforming to schema b will fail because while checking a, the y property gets removed.

@trevorparscal
Copy link

After reading the docs more deeply, it seems this unexpected behavior is well know.

https://ajv.js.org/guide/modifying-data.html#removing-additional-properties

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

No branches or pull requests

2 participants