fastify / fastify/fast-json-stringify

Sibling required keyword is dropped when a property uses $ref to an external schema

Open
#866 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
3.7k
Forks
226
Avg merge
1d 59m
Merged PRs (30d)
3

Description

**What's wrong**

When a property both references an external schema with `$ref` and adds its own
sibling keywords (like `required`), the serializer throws away those sibling
keywords. An object that is missing a required field is accepted and serialized
as valid instead of raising a validation error, so incomplete data passes
through silently.

**Where**

`index.js`, in `buildValue`:
https://github.com/fastify/fast-json-stringify/blob/7fad3c2d6305/index.js#L1300-L1303

```javascript
if (schema.$ref) {
location = resolveRef(context, location)
schema = location.schema
}
```

Resolving the reference replaces the local schema wholesale, so any sibling
keywords on the referencing schema (for example `required`) are gone before the
serializer is generated. The `getValidatorSchemaRef` guard added recently
(`index.js:113`, treats a schema with more than one key as non-pure) correctly
protects validator reference selection in `buildOneOf`/`buildIfThenElse`, but it
does not stop `buildValue` from dereferencing and discarding siblings.

**How it manifests**

1. Register an external `Foo` schema that requires `value`.
2. Create a root schema with a property `x` that uses `$ref: Foo` plus a sibling
`required: ['extra']`.
3. Build the serializer with `Foo` registered as an external schema.
4. Serialize `{ x: { value: 1, extra: "x" } }` and then `{ x: { value: 1 } }`.

Both inputs serialize successfully, even though the second is missing the
sibling-required `extra`.

**Expected behavior**

The sibling `required` constraint should still apply. When a `$ref` has sibling
keywords, resolve the reference as the base schema and then apply the sibling
constraints on top, keeping the direct-dereference optimization only for a
schema that contains `$ref` alone.

Found while running [Ito](https://ito.ai) (AI code review, free for open source) against recently merged PRs. Full analysis: https://app.ito.ai/share/29ad67b0-500d-45d1-9ffd-df265504fb5f.

Contributor guide

Open the contributing guide

Research direction

Start in index.js at buildValue around the external $ref resolution and read the getValidatorSchemaRef guard near index.js:113 for related behavior. Reproduce the Foo schema case with a $ref and sibling required keyword, then verify that complete input serializes while input missing extra raises a validation error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.