atlassian / atlassian/better-ajv-errors
Misleading error when describing deeply nested `anyOf` failure
- Dominant language
- JavaScript
- Stars
- 245
- Forks
- 50
- PR merge metrics
- No merged PRs in 30d
Description
See minimal, verifiable test case, below.
Briefly, the case below is failing due to the type of the `defaultConfigPath` property being incorrect (`boolean` instead of `string`).
**Expected Result**:
I would expect to see an error message along the lines of "'defaultConfigPath' must be a string, not a boolean" in this case. Or at least an error that summarizes the errors for each of the `anyOf` item failure conditions.
**Actual Result**:
BAE describes the error for the second `anyOf` condition, but not the first:

**Editorial**:
If BAE has to choose just one of many errors passed to it, would it make sense to select error with the deepest `schemaPath`? Or maybe `instancePath`? Intuition tells me that the "deeper" an error is within a data structure, the more likely it is to be something the user can meaningfully act upon.
```jsonc
[
{
// This is the error I would most expect/like to see in this case
instancePath: '/processor/defaultConfigPath',
schemaPath: '#/properties/processor/anyOf/0/properties/defaultConfigPath/type',
keyword: 'type',
params: { type: 'string' },
message: 'must be string'
},
{
// This error, while technically correct, isn't all that relevant since the data doesn't
// match any properties in this sub-schema
instancePath: '/processor',
schemaPath: '#/properties/processor/anyOf/1/required',
keyword: 'required',
params: { missingProperty: 'defaultConfigPackageKey' },
message: "must have required property 'defaultConfigPackageKey'"
},
{
// This error is least likely to be meaningful. And fixing one of the above errors will fix this error.
instancePath: '/processor',
schemaPath: '#/properties/processor/anyOf',
keyword: 'anyOf',
params: {},
message: 'must match a schema in anyOf'
}
]
```
----
## Minimal, stand-alone test case
```js
#!/usr/bin/env node
import Ajv from 'ajv';
import betterAjvErrors from 'better-ajv-errors';
const SCHEMA = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
processor: {
anyOf: [
{
additionalProperties: false,
type: 'object',
properties: {
defaultConfig: {
type: 'object',
properties: {},
additionalProperties: true
},
defaultConfigPath: {
type: 'string'
}
},
required: ['defaultConfigPath']
},
{
additionalProperties: false,
type: 'object',
properties: {
defaultConfigPackageKey: {
type: 'string'
}
},
required: ['defaultConfigPackageKey']
}
]
}
}
};
const DATA_TO_VALIDATE = `{
"stuff": "... we don't care about",
"processor":{
"defaultConfigPath": true
}
}`;
const validate = new Ajv().compile(SCHEMA)
const data = JSON.parse(DATA_TO_VALIDATE);
if (!validate(data) && validate.errors) {
console.log(
betterAjvErrors(validate.schema, data, validate.errors, { json: DATA_TO_VALIDATE })
);
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Run the standalone JavaScript reproduction with the supplied schema, data, and validation errors, then inspect how better-ajv-errors chooses which nested anyOf failure to display. Compare the output with the requested deeply nested type error and the alternative of summarizing each anyOf failure; done means the misleading result is replaced by an actionable error or clear summary.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100