JSON Schema draft v4 - additional Properties error with anyOf

18 Views Asked by At

I get an additionalProperties error, I dont get the error when allowing additionalProperties before the anyOf and where i marked <-Here in the code.

Maybe some one knows and can explain the issue to me.

    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "Media",
    "additionalProperties": false,
    "anyOf": [
        {
            "type": "object",
            "properties": {
                "series": {
                    "type": "object",
                    "title": "Series",
                    "properties": {
                        "folder-path": {
                            "type": "string",
                            "title": "Folder-path"
                        },
                        "seasons": {
                            "type": "array",
                            "title": "Seasons",
                            "additionalItems": false,
                            "uniqueItems": true,
                            "items": {
                                "type": "object",
                                "properties": {
                                    "folder-path": {
                                        "type": "string",
                                        "title": "Folder-path"
                                    },
                                    "season-name": {
                                        "type": "string",
                                        "title": "Season-name"
                                    },
                                    "episodes": {
                                        "type": "array",
                                        "title": "Episodes",
                                        "additionalItems": false,
                                        "uniqueItems": true,
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "episode-name": {
                                                    "type": "string",
                                                    "title": "Episode-name"
                                                },
                                                "description": {
                                                    "type": "string",
                                                    "title": "Description"
                                                },
                                                "video-file": {
                                                    "type": "string",
                                                    "title": "Video-file"
                                                },
                                                "cover-file": {
                                                    "type": "string",
                                                    "title": "Cover-file"
                                                }
                                            },
                                            "additionalProperties": false,
                                            "required": [
                                                "episode-name",
                                                "video-file"
                                            ]
                                        }
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                    "folder-path",
                                    "season-name"
                                ]
                            }
                        }
                    },
                    "additionalProperties": false,
                    "required": [
                        "folder-path"
                    ]
                }
            },
            "additionalProperties": false, <-Here
            "required": [
                "series"
            ]
        },
        {
            "type": "object",
            "properties": {
                "movie": {
                    "type": "object",
                    "title": "Movie",
                    "properties": {
                        "video-file": {
                            "type": "string",
                            "title": "Video-file"
                        },
                        "sub-titles": {
                            "type": "array",
                            "title": "Subtitle-files",
                            "additionalItems": true,
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    "additionalProperties": false,
                    "required": [
                        "video-file"
                    ]
                }
            },
            "additionalProperties": false, <-Here
            "required": [
                "movie"
            ]
        }
    ]
}
1

There are 1 best solutions below

2
Jeremy Fiel On BEST ANSWER

No instance will ever pass this schema because you have an additionalProperties: false at the root. This constraint doesn't allow any properties which are undefined at the root, which includes all subschemas (anyOf, allOf, oneOf) because they are not in the same scope as the root schema.

    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "Media",
    "additionalProperties": false,  <---THIS
    "anyOf": [
...

Maintaining the constraint inside your anyOf subschema would be the correct way to go for this example.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Media",
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "series": {
          "type": "object",
          "title": "Series",
          "properties": {
            "folder-path": {
              "type": "string",
              "title": "Folder-path"
            },
            "seasons": {
              "type": "array",
              "title": "Seasons",
              "additionalItems": false,
              "uniqueItems": true,
              "items": {
                "type": "object",
                "properties": {
                  "folder-path": {
                    "type": "string",
                    "title": "Folder-path"
                  },
                  "season-name": {
                    "type": "string",
                    "title": "Season-name"
                  },
                  "episodes": {
                    "type": "array",
                    "title": "Episodes",
                    "additionalItems": false,
                    "uniqueItems": true,
                    "items": {
                      "type": "object",
                      "properties": {
                        "episode-name": {
                          "type": "string",
                          "title": "Episode-name"
                        },
                        "description": {
                          "type": "string",
                          "title": "Description"
                        },
                        "video-file": {
                          "type": "string",
                          "title": "Video-file"
                        },
                        "cover-file": {
                          "type": "string",
                          "title": "Cover-file"
                        }
                      },
                      "additionalProperties": false,
                      "required": [
                        "episode-name",
                        "video-file"
                      ]
                    }
                  }
                },
                "additionalProperties": false,
                "required": [
                  "folder-path",
                  "season-name"
                ]
              }
            }
          },
          "additionalProperties": false,
          "required": [
            "folder-path"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "series"
      ]
    },
    {
      "type": "object",
      "properties": {
        "movie": {
          "type": "object",
          "title": "Movie",
          "properties": {
            "video-file": {
              "type": "string",
              "title": "Video-file"
            },
            "sub-titles": {
              "type": "array",
              "title": "Subtitle-files",
              "additionalItems": true,
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false,
          "required": [
            "video-file"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "movie"
      ]
    }
  ]
}

passing instances:

{
  "series": {
    "folder-path": "1"
  }
}
{
  "movie": {
    "video-file": "1"
  }
}

failing instances

{
  "movie": {
    "video-file": "1"
  },
  "stack": 1
}
{
  "series": {
    "folder-path": "1"
  },
  "stack": 1
}

src: Understanding JSON Schema Scope