JSON Schema `required` allows empty string for value

11,909

Your problem here is you are expecting required to check the value of the key, which it does not.

Required from the current draft-7 specification:

An object instance is valid against this keyword if every item in the array is the name of a property in the instance.

This means required only checks that the key exists for the object. It is not related to the value. For string validation, see the validation key words which are applicable to strings. I suspect you want minLength or pattern (which is regex).

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.3

Share:
11,909
Jake12342134
Author by

Jake12342134

Updated on August 01, 2022

Comments

  • Jake12342134
    Jake12342134 over 1 year

    I'm using a JSON schema template to validate the data that is received by an online form. One of the requirements of the validator is that it allows some questions to be required based on the answers given for other questions.

    For example if the question is Do you want a loan? and the user answers yes, then the answer to the question What is the loan to be used for? needs to be set to required so that the user must provide an answer. If the answer is no then the second question is not required.

    I'm using definitions to define my questions, and then referencing them below in the main question schema. I read that by using the if-then-else feature provided in draft-07 I could use it to set certain questions to be required based on answers to other questions.

    In this particular instance what I would like to happen is that if the user enters the answer Home improvements (General) for question 9, then question 257 will be set to required and MUST be answered, otherwise an error should be thrown.

    At the moment, when I enter this validator into https://www.jsonschemavalidator.net/ it does not work as expected. What actually happens is the answer for question 257 can be left blank even if the answer to question 9 is "Home improvements (General)

    How can I change my schema to give the behaviour I am trying to get?

    JSON Schema

    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "question3-9": {
          "type": "object",
          "properties": {
            "answer": {
              "type": "string",
              "enum": [
                "Home improvements (General)",
                "Other"
              ]
            }
          }
        },
        "question3-257": {
          "type": "object",
          "properties": {
            "answer": {
              "type": "string",
            }
          }
        }
      },
      "type": "object",
      "properties": {
        "form_submission": {
          "type": "object",
          "properties": {
            "sections": {
              "type": "object",
              "properties": {
                "3": {
                  "type": "object",
                  "properties": {
                    "questions": {
                      "type": "object",
                      "properties": {
                        "9": {
                          "$ref": "#/definitions/question3-9"
                        },
                        "257": {
                          "$ref": "#/definitions/question3-257"
                        }
                      },
                      "if": {
                        "properties": {
                          "9": {
                            "properties": {
                              "answer": {
                                "enum": [
                                  "Home improvements (General)"
                                ]
                              }
                            }
                          }
                        }
                      },
                      "then": {
                        "required": [
                          "257"
                        ]
                      }
                    }
                  }
                }
              },
              "required": [
                "3"
              ]
            }
          }
        }
      }
    }
    

    JSON to be validated:

    {
      "form_submission": {
        "sections": {
          "3": {
            "questions": {
              "9": {
                "answer": "Home improvements (General)",
              },
              "257": {
                "answer": "",
              }
            }
          }
        }
      }
    }
    

    Updated If-Then

    "if": {
      "properties": {
        "9": {
          "properties": {
            "answer": {
              "enum": [
                "Home improvements (General)"
              ]
            }
          },
          "required": ["answer"]
        }
      },
      "required": ["9"]
    },
    "then": {
      "257": {
        "properties":{
          "answer":{
            "minLength": 1
          }
        }
      }
    }
    
  • Jake12342134
    Jake12342134 about 5 years
    Hi, I've updated my If-Then within my schema, but it still does not seem to be enforcing the minLength of question 257's answer properly. Am I referencing the answer field properly within my then clause? I have updated the OP with my new If-Then at the bottom.
  • Relequestual
    Relequestual about 5 years
    OK. I've debugged the schema by first testing your if condition evaluation by making then equal false. The value of then must be a schema... so if you were to take the value of then on it's own, you'll see it doesn't add any validation cinstraints, because you need to wrap "257" within properties.
  • myuce
    myuce about 4 years
    very nice answer. Difference between required and string contraints. Just as a ps, required is enforced if the field is null, but not when is empty. This answer should be selected as correct answer, if you ask me.