How to make anyOf a set of mutually exclusive properties except one

Interesting! There might be a neater solution, but here we go...

The "mutually exclusive" constraint can be expressed by banning pairwise combinations of the properties:

{
    "not": {
        "anyOf": [
            {"required": ["baz", "buzz"]},
            {"required": ["buzz", "fizz"]},
            {"required": ["fizz", "baz"]}
        ]
    }
}

The "at least one of" constraint can be expressed with anyOf:

{
    "anyOf": [
        {"required": ["foo"]},
        {"required": ["baz"]},
        {"required": ["buzz"]},
        {"required": ["fizz"]}
    }
}

If you just combine these two constraints into a single schema, then it should work:

{
    "not": {"anyOf": [...]},
    "anyOf": ...
}

You can make properties mutually exclusive in JSON Schema using pairwise exclusions, but this leads to combinatorial explosion. That becomes a problem when you have many mutually exclusive properties.

A linear solution is of the form:

  • one of:
    • property a
    • property b
    • property c
    • not any of:
      • property a
      • property b
      • property c

This only pays off if you have many properties.

{ "oneOf": [
  { "required": ["baz"] },
  { "required": ["buzz"] },
  { "required": ["fizz"] },
  { "not":
    { "anyOf": [
      { "required": ["baz"] },
      { "required": ["buzz"] },
      { "required": ["fizz"] }
    ] }
  }
] }

Combine this with @cloudfeet's answer to get the answer to your specific question.