Search code examples
jsonvalidationschemajsonschemapython-jsonschema

JSON schema failed to resolve $ref, Expected StartObject Bolean, got String


Subschema in another file can't be resolved by $ref

Error Message: Unexpected token encountered when reading value for '$ref'. Expected StartObject, Boolean, got String. Path 'properties.organization.items.properties.$ref'

Root schema

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "https://example.com/schema_root.json",
    "type": "object",
    "properties": {
        "organization": {
            "description": "Organization information associated with the sample",
            "type": "array",
            "items": {
                    "$ref": "organisation.json#"
            }
        }
    }
}

The subschema is in the same directory in file organisation.json

{
    "$id": "organisation",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "Organisation",
    "additionalProperties": false,
    "type": "object",
    "properties": {
        "Name": {
            "type": "string"
        },
        "Role": {
            "type": "string"
        }
    }
}

It seems to me that the root schema could locate the subschema. However, because of some data type discrepancy, it can't load the subschema. But I am not sure what the discrepancy is?

In the Error message Expected StartObject.got String I am not sure what StartObject is and what the String refers to.


Solution

  • There are two problems.

    1. There is an extension (.json) on the reference path, but not the identifier path.
    2. References are resolved against the $id changing how you would identify the second schema.

    Hopefully, this isn't too terse to follow, but here's what happens.

    // From Root Schema
    "$id":  "http://example.com/schema_root.json"
    "$ref": "organization.json#"
    
    // $ref resolves to ...
    "$ref": "http://example.com/organization.json#"
    
    // Expected $id
    "$id": "http://example.com/organization.json"
    
    // Actual $id
    "$id":                    "organization"
    

    The identifier from the reference doesn't match the $id in the second schema, so the validator can't find the schema it needs.