How to validate empty array of strings with ajv?

NtsDK picture NtsDK · Jun 5, 2016 · Viewed 7.5k times · Source

I make json validation with ajv. I need to validate array of strings. I know which elements can be placed there so I make appropriate 'enum'. But in some case enum can be empty and array can be empty too. Here is simple test:

var schema = {
    "type":"array",
    "items" : {
        "type" : "string",
        "enum" : []
    }
}

var data = [];

var Ajv = require('./ajv-4.1.1.js');
var ajv = Ajv({
    allErrors : true
});
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid)
    console.log(validate.errors);

As a result I get:

Error: schema is invalid:data.items.enum should NOT have less than 1 items, data.items should be array, data.items should match some schema in anyOf

I can add any fictive string to enum array but is it possible to validate this case in legal way? Adding 'minItems=0' restriction doesn't help.

Is it really json schema draft restriction that I can't use empty enum?

UPD: I expect to validate code in general case:

var array = Object.keys(someObj); // array: ["foo", "bar"]

var schema = {
    "type":"array",
    "items" : {
        "type" : "string",
        "enum" : array 
    }
}

var data = ["foo"]; // valid
var data = ["bar"]; // valid
var data = ["bar","foo"]; // valid

I expect to validate code in special case:

var array = Object.keys(someObj); // array: []

var schema = {
    "type":"array",
    "items" : {
        "type" : "string",
        "enum" : array 
    }
}

var data = []; // I expect to see it valid too but get error instead.

Answer

Jason Desrosiers picture Jason Desrosiers · Jun 6, 2016

The enum keyword is required to have at least one value. The specification states ...

5.5.1.1. Valid values

The value of this keyword MUST be an array. This array MUST have at least one element. Elements in the array MUST be unique.

Elements in the array MAY be of any type, including null.

This makes sense because an empty enum would mean nothing would ever validate. However, I do see how it could come in handy in your particular case. If you need to build the schema dynamically, you will need to check for the empty array case and use a different schema.

Here's one way to do it:

{
  "type": "array",
  "maxItems": 0
}

Here's another:

{
  "type": "array",
  "not": {}
}