Looking to master JSON Schema for OpenAPI?

A 9+ hour course taught by a member of the JSON Schema Technical Steering Committee

$recursiveRef : URI Reference

$recursiveRef

URI Reference

This keyword is used to reference an identified schema, deferring the full resolution until runtime, at which point it is resolved each time it is encountered while evaluating an instance.

Value This keyword must be set to the empty fragment # Hint: Use the jsonschema metaschema and jsonschema lint commands to catch keywords set to invalid values
Kind Applicator
Applies To Any
Base Dialect 2019-09
Changed In None
Introduced In 2019-09
Vocabulary Core
Specification https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.4.2.1
Metaschema https://json-schema.org/draft/2019-09/meta/core
Official Tests draft2019-09/recursiveRef.json
Default None
Annotation None
Affected By
Affects None
Also See

The $recursiveRef keyword is an extension of the $ref keyword that enables a schema to reference another schema by its recursive anchor, as declared by the $recursiveAnchor keyword. When resolving a recursive anchor using this keyword, the base URI of the origin is not considered. Instead, the evaluator looks in the dynamic scope and jumps to the first encountered occurrence of the recursive anchor in the stack of schema resources traversed so far.

In other words, think of a schema declaring the recursive reference as a reference that considers that its destination might have been re-defined by a parent schema. For example, a schema that references the recursive anchor says: “jump to the location set by the recursive anchor, but if there are overridden variants of it, jump to the first of those instead”.

To debug which recursive anchor the evaluation process is jumping to, try the jsonschema validate command with the --trace option. This option prints a trace of every step in the evaluation process alongside the corresponding keywords and their respective locations, letting you know which destination was preferred when encountering a recursive reference. For example:

$ jsonschema validate custom-metaschema.json schema.json --trace
...

-> (push) "/$ref/allOf/1/$ref/properties/additionalProperties/$recursiveRef" (ControlDynamicAnchorJump)
   at "/additionalProperties"
   at keyword location "https://json-schema.org/draft/2019-09/meta/applicator#/properties/additionalProperties/$recursiveRef"
   at vocabulary "https://json-schema.org/draft/2019-09/vocab/core"

-> (push) "/$ref/allOf/1/$ref/properties/additionalProperties/$recursiveRef/properties" (LogicalWhenType)
   at "/additionalProperties"
   at keyword location "https://example.com/custom-metaschema#/properties"
   at vocabulary "https://json-schema.org/draft/2019-09/vocab/applicator"
...

Examples

A custom meta-schema that extends the JSON Schema 2019-09 dialect with a custom keyword Schema
{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "$id": "https://example.com/custom-metaschema",
  "$recursiveAnchor": true,
  "$ref": "https://json-schema.org/draft/2019-09/schema",
  "properties": {
    "my-custom-keyword": { "type": "string" }
  }
}
Valid An object with a top-level occurrence of the custom keyword is valid Instance
{ "my-custom-keyword": "foo" }
Annotations
{ "keyword": "/properties", "instance": "", "value": [ "my-custom-keyword" ] }
Valid An object with a nested occurrence of the custom keyword is valid Instance
{ "additionalProperties": { "my-custom-keyword": "foo" } }
Annotations
{ "keyword": "/properties", "instance": "/additionalProperties", "value": [ "my-custom-keyword" ] }
Invalid An object with an incorrect nested occurrence of the custom keyword is invalid Instance
{ "additionalProperties": { "my-custom-keyword": 1 } }