ajv-errors
ajv-errors copied to clipboard
Default error message does not produce consistent output for `oneOf` nested in an array (expect 1 errors in output)
[email protected]
[email protected]
Greets,
I have included schema and simple test case below showing that a default error message does not produce consistent results. For some reason the "nested" oneOf statement w/ default error message produces two entries in the errors
output. The oneOf statement at the top level which is exactly the same produces one entry in the errors
output.
IE for the schema below the entry count with the default error message should be the same for both failing validation cases:
{ system: [false] }
and { packs: [{ system: [false] }] }
The latter is not picking up the child items type error in the default error message which is part of the oneOf block.
const Ajv = require("ajv").default;
const ajv = new Ajv({ allErrors: true });
// Ajv option allErrors is required
require("ajv-errors")(ajv);
const schema = {
$id: "test",
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
packs: {
type: "array",
items: {
type: "object",
properties: {
system: {
oneOf: [
{ type: "string" },
{
items: { type: "string" },
type: "array"
}
],
errorMessage: "should be a string or array of strings"
}
}
}
},
system: {
oneOf: [
{ type: "string" },
{
items: { type: "string" },
type: "array"
}
],
errorMessage: "should be a string or array of strings"
}
}
};
const validate = ajv.compile(schema);
// Expect `errorMessage` to catch all errors at or below the oneOf level.
console.log(`{ system: [false] }:`);
console.log(JSON.stringify(validate.errors, null, 3));
// Expect `errorMessage` to catch all errors at or below the oneOf level.
// However it does not catch the further items type and there are two errors.
console.log('\n-------------------------------------------------------------\n');
console.log(`expect only one error in 'errors', but there are two for { packs: [{ system: [false] }] }:`);
console.log(JSON.stringify(validate.errors, null, 3));
#Output:
{ system: [false] }:
[
{
"keyword": "errorMessage",
"dataPath": "/system",
"schemaPath": "#/properties/system/errorMessage",
"params": {
"errors": [
{
"keyword": "type",
"dataPath": "/system",
"schemaPath": "#/properties/system/oneOf/0/type",
"params": {
"type": "string"
},
"message": "should be string",
"emUsed": true
},
{
"keyword": "type",
"dataPath": "/system/0",
"schemaPath": "#/properties/system/oneOf/1/items/type",
"params": {
"type": "string"
},
"message": "should be string",
"emUsed": true
},
{
"keyword": "oneOf",
"dataPath": "/system",
"schemaPath": "#/properties/system/oneOf",
"params": {
"passingSchemas": null
},
"message": "should match exactly one schema in oneOf",
"emUsed": true
}
]
},
"message": "should be a string or array of strings"
}
]
-------------------------------------------------------------
expect only one error in 'errors', but there are two for { packs: [{ system: [false] }] }:
[
{
"keyword": "type",
"dataPath": "/packs/0/system/0",
"schemaPath": "#/properties/packs/items/properties/system/oneOf/1/items/type",
"params": {
"type": "string"
},
"message": "should be string"
},
{
"keyword": "errorMessage",
"dataPath": "/packs/0/system",
"schemaPath": "#/properties/packs/items/properties/system/errorMessage",
"params": {
"errors": [
{
"keyword": "type",
"dataPath": "/packs/0/system",
"schemaPath": "#/properties/packs/items/properties/system/oneOf/0/type",
"params": {
"type": "string"
},
"message": "should be string",
"emUsed": true
},
{
"keyword": "oneOf",
"dataPath": "/packs/0/system",
"schemaPath": "#/properties/packs/items/properties/system/oneOf",
"params": {
"passingSchemas": null
},
"message": "should match exactly one schema in oneOf",
"emUsed": true
}
]
},
"message": "should be a string or array of strings"
}
]