title: How to conditionally forbid properties based on presence of other properties in JSON Schema?
body: <p>In my schema I declared these properties:</p>
  
  <pre><code>"index_name": {
        "type": "string",
        "examples": ["foo-wwen-live", "foo"]
      },
  "locale": {
        "type": "string",
        "examples": ["wwen", "usen", "frfr"]
  },
  "environment": {
        "type": "string",
        "default": "live",
        "examples": [
          "staging",
          "edgengram",
          "test"
        ]
  }
  </code></pre>
  
  <p>I want a JSON body validated against my schema to be valid <strong>only if</strong>:</p>
  
  <ul>
  <li><code>index_name</code> <strong>is</strong> present, and <strong>both</strong> <code>locale</code> and <code>environment</code> <strong>are not</strong> present;</li>
  <li><code>locale</code> and/or <code>enviroment</code> <strong>are</strong> present, and <code>index_name</code> <strong>is not</strong> present</li>
  </ul>
  
  <p>In short, <code>locale</code> and <code>environment</code> should never be mixed with <code>index_name</code>.</p>
  
  <h2>Test cases and desired results:</h2>
  
  <p><strong>These should pass:</strong><br>
  Case #1</p>
  
  <pre><code>{
    "locale": "usen"
  }
  </code></pre>
  
  <p>Case #2</p>
  
  <pre><code>{
    "environment": "foo"
  }
  </code></pre>
  
  <p>Case #3</p>
  
  <pre><code>{
    "environment": "foo",
    "locale": "usen"
  }
  </code></pre>
  
  <p>Case #4</p>
  
  <pre><code>{
    "index_name": "foo-usen"
  }
  </code></pre>
  
  <p><strong>These should NOT pass:</strong><br>
  Case #5</p>
  
  <pre><code>{
    "index_name": "foo-usen",
    "locale": "usen"
  }
  </code></pre>
  
  <p>Case #6</p>
  
  <pre><code>{
    "index_name": "foo-usen",
    "environment": "foo"
  }
  </code></pre>
  
  <p>Case #7</p>
  
  <pre><code>{
    "index_name": "foo-usen",
    "locale": "usen",
    "environment": "foo"
  }
  </code></pre>
  
  <p>I created the following rule for my schema, however it does not cover all the cases. For example, if both <code>locale</code> and <code>environment</code> are present, validation returns failure if <code>index_name</code> is also present, which is correct behavior according to case #7. But if only one of <code>locale</code> and <code>environment</code> is present, it allows <code>index_name</code> to also be present (fails at cases #5 and #6).</p>
  
  <pre><code>  "oneOf": [
      {
        "required": ["index_name"],
        "not": {"required":  ["locale", "environment"]}
      },
      {
        "anyOf": [
          {
            "required": ["locale"],
            "not": {"required": ["index_name"]}
          },
          {
            "required": ["environment"],
            "not": {"required": ["index_name"]}
          }
        ]
      }
    ]
  </code></pre>
  
  <p>I'm getting mixed information on how <code>"not": {"required": []}</code> declaration works. <a href="https://stackoverflow.com/a/30675218/6158307">Some people</a> claim this means that it forbids anything declared in the array to be present, in contrary to what idea does the syntax give. <a href="https://stackoverflow.com/a/25637397/6158307">Other claim</a> that this should be taken exactly as it sounds: properties listed in the array are <strong>not required</strong> - they can be present, but it doesn't matter if they aren't.</p>
  
  <p>Apart from this rule, I also require one non-related property to be present in all cases and I set <code>"additionalProperties": false</code>.</p>
  
  <p>What is the rule that would satisfy all my test cases?</p>