title: JSON schema: Why does "constant" not validate the same way as a single-valued "enum"?
body: <p>I have an object that provides a sort of audit log of versions of an asset. A couple of its properties (<code>versionSource.metadata</code> and <code>versionSource.files</code>) are objects that should validate against one of two schemas, depending on the value of one of their properties. I started off using a constant in my sub-schemas (inside the <code>oneOf</code>, but that was saying that all the the sub-schemas validated (thus breaking the <code>oneOf</code> since more than one validated. Changing it to a single-valued enum worked, though.</p>
  
  <p>Why the difference in validation?</p>
  
  <p>Here's the original schema:</p>
  
  <pre><code>{
     "$id": "https://example.com/schemas/asset-version.json",
     "title": "Audit log of asset versions",
     "$schema": "http://json-schema.org/draft-07/schema",
  
     "type": "object",
     "required": [
        "assetID",
        "version",
        "versionSource"
     ],
  
     "properties": {
        "assetID": {
           "type": "string"
        },
        "version": {
           "type": "integer",
           "minimum": 1
        },
        "versionSource": {
           "type": "object",
           "properties": {
              "metadata": {
                 "type": "object",
                 "oneOf": [
                    {
                       "properties": {
                          "sourceType": { "constant": "client" }
                       }
                    },
                    {
                       "$ref": "#/definitions/version-source-previous-version"
                    }
                 ]
              },
              "files": {
                 "type": "object",
                 "oneOf": [
                    {
                       "properties": {
                          "sourceType": { "constant": "upload" },
                          "sourceID": {
                             "type": "string"
                          }
                       }
                    },
                    {
                       "$ref": "#/definitions/version-source-previous-version"
                    }
                 ]
              }
           }
        }
     },
  
     "definitions": {
        "version-source-previous-version": {
           "properties": {
              "sourceType": { "constant": "previous-version" },
              "sourceID": {
                 "type": "integer",
                 "minimum": 1
              }
           }
        }
     }
  }
  </code></pre>
  
  <p>Here's one example document:</p>
  
  <pre><code>{
     "assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
     "version": 1,
     "versionSource": {
        "metadata": {
           "sourceType": "client"
        },
        "files": {
           "sourceType": "upload",
           "sourceID": "54ae67b0-3e42-464a-a93f-3143b0f078fc"
        }
     },
     "created": "2018-09-01T00:00:00.00Z",
     "lastModified": "2018-09-02T12:10:00.00Z",
     "deleted": "2018-09-02T12:10:00.00Z"
  }
  </code></pre>
  
  <p>And one more:</p>
  
  <pre><code>{
     "assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
     "version": 2,
     "versionSource": {
        "metadata": {
           "sourceType": "previous-version",
           "sourceID": 1
        },
        "files": {
           "sourceType": "previous-version",
           "sourceID": 1
        }
     },
     "created": "2018-09-01T00:00:00.00Z",
     "lastModified": "2018-09-02T12:10:00.00Z",
     "deleted": "2018-09-02T12:10:00.00Z"
  }
  </code></pre>
  
  <p>Here's the error I get:</p>
  
  <p>Message: JSON is valid against more than one schema from 'oneOf'. Valid schema indexes: 0, 1.
  Schema path:
  <a href="https://example.com/schemas/asset-version.json#/properties/versionSource/properties/metadata/oneOf" rel="noreferrer">https://example.com/schemas/asset-version.json#/properties/versionSource/properties/metadata/oneOf</a></p>
  
  <p>Since <code>sourceType</code> is a constant in both schemas inside the <code>oneOf</code>, I'm really not sure how my object could possibly be valid against both schemas.</p>
  
  <p>Changing the schema to the following, though, worked:</p>
  
  <pre><code>{
     "$id": "https://example.com/schemas/asset-version.json",
     "title": "Audit log of asset versions",
     "$schema": "http://json-schema.org/draft-07/schema",
  
     "type": "object",
     "required": [
        "assetID",
        "version",
        "versionSource"
     ],
  
     "properties": {
        "assetID": {
           "type": "string"
        },
        "version": {
           "type": "integer",
           "minimum": 1
        },
        "versionSource": {
           "type": "object",
           "properties": {
              "metadata": {
                 "type": "object",
                 "oneOf": [
                    {
                       "properties": {
                          "sourceType": { "enum": [ "client" ] }
                       }
                    },
                    {
                       "$ref": "#/definitions/version-source-previous-version"
                    }
                 ]
              },
              "files": {
                 "type": "object",
                 "oneOf": [
                    {
                       "properties": {
                          "sourceType": { "enum": [ "upload" ] },
                          "sourceID": {
                             "type": "string"
                          }
                       }
                    },
                    {
                       "$ref": "#/definitions/version-source-previous-version"
                    }
                 ]
              }
           }
        }
     },
  
     "definitions": {
        "version-source-previous-version": {
           "properties": {
              "sourceType": { "enum": [ "previous-version" ] },
              "sourceID": {
                 "type": "integer",
                 "minimum": 1
              }
           }
        }
     }
  }
  </code></pre>
  
  <p>What am I missing?</p>