fastify / fastify/fast-json-stringify
Coercion rules are not working with anyOf
- Dominant language
- JavaScript
- Stars
- 3.7k
- Forks
- 226
- Avg merge
- 1d 59m
- Merged PRs (30d)
- 3
Description
### Prerequisites
- [x] I have written a descriptive issue title
- [x] I have searched existing issues to ensure the bug has not already been reported
### Fastify version
5.6.2
### Plugin version
6.1.1
### Node.js version
v24.10.0
### Operating system
macOS
### Operating system version (i.e. 20.04, 11.3, 10)
26.0.1
### Description
When using AJV with Fastify, type coercion does not seem to work properly when the schema uses an `anyOf` definition that references another schema.
For example, in the following setup:
```js
const schema = {
$id: 'LogDetails',
type: 'object',
properties: {
statePrevious: {
anyOf: [
// other possible schemas...
{ $ref: 'EntityStateUser#' },
],
},
stateNext: {
anyOf: [
// other possible schemas...
{ $ref: 'EntityStateUser#' },
],
},
},
required: ['statePrevious', 'stateNext'],
};
const schemaEntityStateUser = {
$id: 'EntityStateUser',
type: 'object',
properties: {
id: { type: 'string', format: 'uuid' },
email: { type: 'string' },
name: { type: 'string' },
surname: { type: 'string' },
enabled: { type: 'boolean' },
createdAt: { type: 'string' },
roles: {
type: 'array',
items: { $ref: 'Role#' },
},
},
required: [
'entityType',
'id',
'email',
'name',
'surname',
'enabled',
'createdAt',
'roles',
],
};
fastify.addSchema(schemaEntityStateUser);
fastify.addSchema(schema);
const input = {
statePrevious: {
id: 'abc',
email: 'super secret email',
name: 'Daniele',
surname: 'Sarnari',
enabled: 1, // should be coerced to boolean
createdAt: '26/09/2022 15:49:02',
roles: []
},
stateNext: {
id: 'abc',
email: 'super secret email',
name: 'Daniele',
surname: 'Sarnari',
enabled: 1, // should be coerced to boolean
createdAt: '26/09/2022 15:49:02',
roles: []
},
};
```
According to the AJV documentation on [[type coercion](https://ajv.js.org/coercion.html)](https://ajv.js.org/coercion.html), the `enabled` field (a `boolean` in the schema) should be coerced from `1` to `true`.
However, when the schema is wrapped inside an `anyOf`, coercion **does not occur**, and Fastify returns the following validation error:
```
The value of 'LogDetails#/properties/statePrevious' does not match schema definition.
```
(because ajv is not actively coercing the fields in the nested schemas)
If the same setup is changed to use `allOf` instead of `anyOf`, coercion works as expected - the numeric value `1` is correctly converted to a boolean `true`.
### Link to code that reproduces the bug
the description should be enough, if not just tell me and i will create a repository
### Expected Behavior
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.