Skip to content

Clarify interaction of $ref and sibling properties #672

Closed
@reitzig

Description

@reitzig

I ran into an issue with inconsistent behaviour of different validators which I narrowed down to the following potential ambiguity in the spec (Draft 4).

In short, how do we interpret a schema fragment like this?

{
	"$ref": "#/definitions/foo",
	"enum": ["a"]
}

where

"definitions": {
	"foo": {
		"type": "string",
		"enum": ["a", "b", "c"]
	}
}

Does "b" validate against this schema (fragment)?

My intuition for the semantics of $ref is that sibling nodes would override the referenced schema; ruby-json-schema/json-schema seems to agree. However, neither jsonschemavalidator.net nor java-json-tools/json-schema-validator give the same result.

I couldn't find anything about this in the draft 4 specs. Only an official example suggested that the problem may be with the schema and the Ruby implementation.

I saw #523 and #515 but didn't read them completely; if I understand correctly, my understanding is incorrect and I should use

{
	"allOf": [
		{ "$ref": "#/definitions/foo" },
		{ "enum": ["a"] }
	]
}

This strikes me an unnecessary amount of boilerplate -- above version could easily be specified to mean exactly this -- but well. Is my understanding correct this far?

I assume that the discussion rests on this sentences in section 8.3 of draft 7, whose significance I completely missed during repeated readings:

All other properties in a "$ref" object MUST be ignored.

Even after reading it knowing what it must mean, I don't think it's as clear as it could be; the term "$ref object" is not specified. Proposal:

If property `$ref$ is present in an object schema, all other properties must be ignored.

In addition, I propose to make the specification more strict here: schemas that do not conform to this restriction should not be valid; loud errors are preferable over (presumably silent) ignoring.

MWE

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "A test schema",
  "type": "object",
  "oneOf": [
    {
      "properties": {
        "type": {
          "$ref": "#/definitions/foo",
          "enum": ["a"]
        },
        "name": {
          "type": "string"
        }
      },
      "required": ["type", "name"]
    },
    {
      "properties": {
        "type": {
          "$ref": "#/definitions/foo",
          "enum": ["b"]
        },
        "id": {
          "type": "integer"
        }
      },
      "required": ["type", "id"]
    }
  ],
  "definitions": {
    "foo": {
      "type": "string",
      "enum": ["a", "b", "c"]
    }
  }
}

This schema validates with all abovementioned tools.

{ 
	"type": "a",
	"id": 77
}

This JSON does not validate with ruby-json-schema/json-schema (cf MWE) but validates on jsonschemavalidator.net.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions