6

I want to validate a JSON against a JSON schema with Ajv in JavaScript. I get the error:

throw new it.MissingRefError(it.baseId, $schema, $message); ^ Error: can't resolve reference #/definitions/requestGraph from id requestGetGraphs

When removing reference to other schema: { "$ref" : "#/definitions/requestGraph" } the error disappears.

JavaScript-code:

ajv.addSchema(require('./json-schema/graph-response'), 'graph-response.json');
ajv.validate('requestGetGraphs', `{"type" : "requestGetGraphs", "space" : "config", "v" : 1.1, "id" : "dsaf" }`);

graph-request.json:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id" : "graph-requests.json",
  "definitions": {
    "requestGraph" : {
      "$id" : "#/definitions/requestGraph",
      "allOf" : [
        { "$ref" : "call.json/#/definitions/request" },
        {
          "properties": {
            "space": {
              "$id" : "#requestGraph/properties/space",
              "type": "string",
              "const": "config"
            }
          }
        }
      ]
    }
  },
  "requestGetGraphs" : {
      "$id" : "requestGetGraphs",
      "type" : "object",
      "allOf" : [
        {
          "properties": {
            "action": {
              "$id" : "#requestGetGraphs/properties/action",
              "type": "string",
              "const": "requestGetGraphs"
            }
          }
        },
        { "$ref" : "#/definitions/requestGraph" }
      ]

    }

}
Relequestual
  • 11,631
  • 6
  • 47
  • 83
Skvupp
  • 155
  • 2
  • 3
  • 12

2 Answers2

49

If you are here for the @typescript-eslint related build error can't resolve reference #/definitions/directiveConfigSchema from id # which appeared out of blue yesterday, just downgrade "@typescript-eslint/eslint-plugin" to version "5.33.0". If you don't have it in your package.json just add it (without the ^ in version). Remove your yarn.lock, package-lock.json and node_modules and rebuild.

More information at https://github.com/typescript-eslint/typescript-eslint/issues/5525

detay
  • 1,082
  • 11
  • 19
1

This is to do with URI resolution. Check https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01#section-8.2.2

When an "$id" sets the base URI, the object containing that "$id" and all of its subschemas can be identified by using a JSON Pointer
fragment starting from that location. This is true even of
subschemas that further change the base URI. Therefore, a single
subschema may be accessible by multiple URIs, each consisting of base URI declared in the subschema or a parent, along with a JSON Pointer
fragment identifying the path from the schema object that declares
the base to the subschema being identified. Examples of this are
shown in section 8.2.4.

Because you specified requestGetGraphs without a hash in front, it resolves as if a new schema (because it's not a fragment). Prefixing your $id with a hash signifies it's a fragment identifier, and URI resolution happens accordingly.

You probably also meant to nest requestGetGraphs inside properties, right?

Community
  • 1
  • 1
Relequestual
  • 11,631
  • 6
  • 47
  • 83
  • The reference is inside the same file. I can also read the documentation for ajv. But what is wrong with my code? – Skvupp Apr 16 '19 at 11:20
  • Sorry, I misunderstood. I'll take another look. – Relequestual Apr 16 '19 at 11:27
  • 2
    Thank you, I solved it. I had to set the main root to "$id" : "http://example.com/graph-requests.json#" and put a hash in front of the id on requestGetGraphs. Then I had to validate with ref: graph-requests.json#/requestGetGraphs. Could you delete your first answere? I already got that theory, and the post will be easier to read for others. – Skvupp Apr 16 '19 at 13:16
  • 1
    Super! I'll remove my first answer and edit your question title to better reflect the question. – Relequestual Apr 16 '19 at 13:18
  • You didn't need to set a full root $id, but it's also good practice. – Relequestual Apr 16 '19 at 13:19