alibaba / alibaba/fastjson2

[BUG] JSONSchema silently fails to resolve forward references in $defs (loses validation rules depending on key order)

Open
#7,855 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
4.4k
Forks
613
Avg merge
1d 22h
Merged PRs (30d)
6

Description

### Description
`JSONSchema` silently fails to correctly resolve forward references inside the `$defs` (or `definitions`) block when parsing a schema using `JSONSchema.of()`. It does not throw any exceptions, but quietly loses validation information.

According to the JSON Schema specification, the order of keys in a JSON object is not regulated, and validators must support forward references. However, `fastjson2` processes `$defs` sequentially in a single pass. If a schema definition references another schema that appears later in the `$defs` object, the parser cannot find it in the internal catalog yet. Instead of throwing an error or resolving it lazily, it silently falls back to an empty schema (`{}`), causing incorrect validation behavior.

This issue seems directly related to an incomplete fix in **#1766** (where recursive references were partially introduced). While #1766 fixed certain cyclical cases, the strict key ordering in `$defs` still breaks the parser if the referenced schema hasn't been processed yet during the single-pass iteration.

### Steps to Reproduce
Given a JSON Schema where a definition (`attachments`) references a type (`attachment`) defined later in the `$defs` map:

```json
{
"\$schema": "https://json-schema.org",
"type": "object",
"properties": {
"data": { "\(ref": "#/\)defs/attachments" }
},
"\$defs": {
"attachments": {
"type": "array",
"items": { "\(ref": "#/\)defs/attachment" }
},
"attachment": {
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
}
}
}
```

### Actual Behavior
No exceptions are thrown, but the reference isn't resolved correctly. When `JSONSchema.of` compiles `attachments`, it looks for `#/$defs/attachment` inside `this.defs`. Since the iteration hasn't reached the `attachment` key yet, it is missing from the catalog, resulting in `items` being compiled as an empty schema `{}`.

As a result, the parsed schema for `attachments` incorrectly becomes:
```json
{"type":"array","items":{}}
```
This breaks any strict validation for array items.

### Expected Behavior
The parser should support forward references within `$defs` regardless of the key order. This can be achieved by using a two-pass compilation approach (registering all definitions first, then resolving internal `$ref` links) or utilizing proper lazy evaluation for references.

### Environment
* **Fastjson2 Version:** 2.0.65
* **JDK Version:** 17

Contributor guide

Open the contributing guide

Research direction

Start at the JSONSchema.of() entry point and trace how the $defs or definitions block is compiled and how internal $ref links are looked up. Reproduce the forward-reference example with the definition order shown, then verify that array item validation still requires the attachment id regardless of definition order.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.