fastify / fastify/fast-json-stringify

Coercion rules are not working with anyOf

Open
#805 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.