joi
Installation:

npm: npm install @hapi/joi

yarn: yarn add @hapi/joi

Introduction

joi lets you describe your data using a simple, intuitive, and readable language. Like the rest of the hapi ecosystem it fits in, joi allows you to describe your data for both input and output validation, as part of a hapi HTTP server or standalone.

Example

const Joi = require('@hapi/joi');

const schema = Joi.object({
    username: Joi.string()
        .alphanum()
        .min(3)
        .max(30)
        .required(),

    password: Joi.string()
        .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),

    repeat_password: Joi.ref('password'),

    access_token: [
        Joi.string(),
        Joi.number()
    ],

    birth_year: Joi.number()
        .integer()
        .min(1900)
        .max(2013),

    email: Joi.string()
        .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
    .with('username', 'birth_year')
    .xor('password', 'access_token')
    .with('password', 'repeat_password');


schema.validate({ username: 'abc', birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }

schema.validate({});
// -> { value: {}, error: '"username" is required' }

// Also -

try {
    const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 });
}
catch (err) { }

The above schema defines the following constraints:

  • username
    • a required string
    • must contain only alphanumeric characters
    • at least 3 characters long but no more than 30
    • must be accompanied by birth_year
  • password
    • an optional string
    • must satisfy the custom regex pattern
    • cannot appear together with access_token
    • must be accompanied by repeat_password and equal to it
  • access_token
    • an optional, unconstrained string or number
  • birth_year
    • an integer between 1900 and 2013
  • email
    • a valid email address string
    • must have two domain parts e.g. example.com
    • TLD must be .com or .net

General Usage

Usage is a two steps process:

First, a schema is constructed using the provided types and constraints:

const schema = Joi.object({
    a: Joi.string()
});

Note that joi schema objects are immutable which means every additional rule added (e.g. .min(5)) will return a new schema object.

Second, the value is validated against the defined schema:

const { error, value } = schema.validate({ a: 'a string' });

If the input is valid, then the error will be undefined. If the input is invalid, error is assigned a ValidationError object providing more information.

The schema can be a plain JavaScript object where every key is assigned a joi type, or it can be a joi type directly:

const schema = Joi.string().min(10);

If the schema is a joi type, the schema.validate(value) can be called directly on the type. When passing a non-type schema object, the module converts it internally to an object() type equivalent to:

const schema = Joi.object().keys({
    a: Joi.string()
});

When validating a schema:

  • Values (or keys in case of objects) are optional by default.

    Joi.string().validate(undefined); // validates fine

    To disallow this behavior, you can either set the schema as required(), or set presence to "required" when passing options:

    Joi.string().required().validate(undefined);
    // or
    Joi.string().validate(undefined, /* options */ { presence: "required" });
  • Strings are utf-8 encoded by default.

  • Rules are defined in an additive fashion and evaluated in order, first the inclusive rules, then the exclusive rules.

assert(value, schema, [message], [options])

Validates a value against a schema and throws if validation fails where:

  • value - the value to validate.
  • schema - the validation schema. Can be a joi type object or a plain object where every key is assigned a joi type object using Joi.compile (be careful of the cost of compiling repeatedly the same schemas).
  • message - optional message string prefix added in front of the error message. may also be an Error object.
  • options - optional options object, passed in to any.validate
Joi.assert('x', Joi.number());

attempt(value, schema, [message], [options])

Validates a value against a schema, returns valid object, and throws if validation fails where:

  • value - the value to validate.
  • schema - the validation schema. Can be a joi type object or a plain object where every key is assigned a joi type object using Joi.compile (be careful of the cost of compiling repeatedly the same schemas).
  • message - optional message string prefix added in front of the error message. may also be an Error object.
  • options - optional options object, passed in to any.validate
Joi.attempt('x', Joi.number()); // throws error
const result = Joi.attempt('4', Joi.number()); // result -> 4

cache.provision([options])

Provisions a simple LRU cache for caching simple inputs (undefined, null, strings, numbers, and booleans) where:

  • options - optional settings:
    • max - number of items to store in the cache before the least used items are dropped. Defaults to 1000.

checkPreferences(prefs)

Checks if the provided preferences are valid where:

  • prefs - the preferences object to validate.

Throws an exception if the prefs object is invalid.

The method is provided to perform inputs validation for the any.validate(]) and any.validateAsync() methods. Validation is not performed automatically for performance reasons. Instead, manually validate the preferences passed once and reuse.

compile(schema, [options])

Converts literal schema definition to joi schema object (or returns the same back if already a joi schema object) where:

  • schema - the schema definition to compile.
  • options - optional settings:
    • legacy - if true and the provided schema is (or contains parts) using an older version of joi, will return a compiled schema that is compatible with the older version. If false, the schema is always compiled using the current version and if older schema components are found, an error is thrown.
const definition = ['key', 5, { a: true, b: [/^a/, 'boom'] }];
const schema = Joi.compile(definition);

// Same as:

const schema = Joi.alternatives().try(
    Joi.string().valid('key'),
    Joi.number().valid(5),
    Joi.object({
        a: Joi.boolean().valid(true),
        b: Joi.alternatives().try(
            Joi.string().pattern(/^a/),
            Joi.string().valid('boom')
        )
    })
);

defaults(modifier)

Creates a new joi instance that applies the provided modifier function to every new schemas where:

  • modifier - a function with signature function(schema) that must return a schema object.
const custom = Joi.defaults((schema) => {

    switch (schema.type) {
        case 'string':
            return schema.allow('');
        case 'object':
            return schema.min(1);
        default:
            return schema;
    }
});

const schema = custom.object();   // Returns Joi.object().min(1)

expression(template, [options]) - aliases: x

Generates a dynamic expression using a template string where:

  • template - the template string using the template syntax.
  • options - optional settings used when creating internal references. Supports the same options as ref().

Template syntax

The template syntax uses {} and {{}} enclosed formulas to reference values as well as perform number and string operations. Single braces {} leave the formula result as-is, while double braces {{}} HTML-escape the formula result (unless the template is used for error messages and the errors.escapeHtml preference flag is set to false).

The formula uses a simple mathematical syntax such as a + b * 2 where the named formula variables are references. Most references can be used as-is but some can create ambiguity with the formula syntax and must be enclosed in [] braces (e.g. [.]).

The formulas can only operate on null, booleans, numbers, and strings. If any operation involves a string, all other numbers will be casted to strings (as the internal implementation uses simple JavaScript operators). The supported operators are: ^, *, /, %, +, -, <, <=, >, >=, ==, !=, &&, ||, and ?? (in this order of precedence).

The reference names can have one of the following prefixes:

  • # - indicates the variable references a local context value. For example, in errors this is the error context, while in rename operations, it is the regular expression matching groups.
  • $ - indicates the variable references a global context value from the context preference object provided as an option to the validation function or set using any.prefs().
  • any other variable references a key within the current value being validated.

The formula syntax also supports built-in functions:

  • if(condition, then, otherwise) - returns then when condition is truthy, otherwise otherwise.
  • msg(code) - embeds another error code message.
  • number(value) - cast value to a number.

And the following constants:

  • null
  • true
  • false

extend(...extensions)

Creates a new customized instance of the joi module where:

  • extensions - the extensions configurations as described in Extensions.

Note that the original joi module is not modified by this.

isExpression(expression)

Checks whether or not the provided argument is an expression.

const expression = Joi.x('{a}');
Joi.isExpression(expression); // returns true

in(ref, [options])

Creates a reference that when resolved, is used as an array of values to match against the rule, where:

Can only be used in rules that support in-references.

const schema = Joi.object({
    a: Joi.array().items(Joi.number()),
    b: Joi.number().valid(Joi.in('a'))
});

isRef(ref)

Checks whether or not the provided argument is a reference. Useful if you want to post-process error messages.

const ref = Joi.ref('a');
Joi.isRef(ref); // returns true

isSchema(schema, [options])

Checks whether or not the provided argument is a joi schema where:

  • schema - the value being checked.
  • options - optional settings:
    • legacy - if true, will identify schemas from older versions of joi, otherwise will throw an error. Defaults to false.
const schema = Joi.any();
Joi.isSchema(schema); // returns true

override

A special value used with any.allow(), any.invalid(), and any.valid() as the first value to reset any previously set values.

Joi.valid(1).valid(Joi.override, 2);

// Same as:

Joi.valid(2);

// Whereas:

Joi.valid(1).valid(2);

// Is the same as:

Joi.valid(1, 2);

ref(key, [options])

Generates a reference to the value of the named key. References are resolved at validation time and in order of dependency so that if one key validation depends on another, the dependent key is validated second after the reference is validated.

References support the following arguments:

  • key - the reference target. References can point to sibling keys (a.b) or ancestor keys (...a.b) using the . separator. If a key starts with $ is signifies a context reference which is looked up in the context option object. The key can start with one or more separator characters to indicate a relative starting point.
  • options - optional settings:
    • adjust - a function with the signature function(value) where value is the resolved reference value and the return value is the adjusted value to use. For example (value) => value + 5 will add 5 to the resolved value. Note that the adjust feature will not perform any type validation on the adjusted value and it must match the value expected by the rule it is used in. Cannot be used with map.
    • map - an array of array pairs using the format [[key, value], [key, value]] used to maps the resolved reference value to another value. If the resolved value is not in the map, it is returned as-is. Cannot be used with adjust.
    • prefix - overrides default prefix characters key string prefix. Can be set to false to disable all prefix parsing (treat keys as literal strings), or an object with specific overrides for:
      • global - references to the globally provided context preference. Defaults to '$'.
      • local - references to error-specific or rule specific context. Defaults to '#'.
      • root - references to the root value being validated. Defaults to '/'.
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
    • ancestor - if set to a number, sets the reference relative starting point. Cannot be combined with separator prefix characters. Defaults to the reference key prefix (or 1 if none present).
    • in - creates an in-reference.
    • iterables - when true, the reference resolves by reaching into maps and sets.

Note that references can only be used where explicitly supported such as in valid() or invalid() rules. If upwards (parents) references are needed, use object.assert().

const schema = Joi.object({
    a: Joi.ref('b.c'),
    b: {
        c: Joi.any()
    },
    c: Joi.ref('$x')
});

await schema.validateAsync({ a: 5, b: { c: 5 } }, { context: { x: 5 } });

Relative references

By default, a reference is relative to the parent of the current value (the reference key is lookup up inside the parent). This means that in the schema:

{
    x: {
        a: Joi.any(),
        b: {
            c: Joi.any(),
            d: Joi.ref('c')
        }
    },
    y: Joi.any()
}

The reference Joi.ref('c') points to c which is a sibling of d - the reference starting point is d's parent which is b. This schema means that d must be equal to c.

In order to reference a parent peer, you can use a separator prefix where (using . as separator):

  • . - self
  • .. - parent (same as no prefix)
  • ... - grandparent
  • .... - great-grandparent
  • etc.

For example:

{
    x: {
        a: Joi.any(),
        b: {
            c: Joi.any(),
            d: Joi.ref('c'),
            e: Joi.ref('...a'),
            f: Joi.ref('....y')
        }
    },
    y: Joi.any()
}

Another way to specify the relative starting point is using the ancestor option where:

  • 0 - self
  • 1 - parent (this is the default value if no key prefix is present)
  • 2 - grandparent
  • 3 - great-grandparent
  • etc.

For example:

{
    x: {
        a: Joi.any(),
        b: {
            c: Joi.any(),
            d: Joi.ref('c', { ancestor: 1 }),
            e: Joi.ref('a', { ancestor: 2 }),
            f: Joi.ref('y', { ancestor: 3 })
        }
    },
    y: Joi.any()
}

Note that if a reference tries to reach beyond the value root, validation fails.

To specify an absolute path from the value root, use the / prefix:

{
    x: {
        a: Joi.any(),
        b: {
            c: Joi.ref('/x.a')
        }
    }
}

version

Property showing the current version of joi being used.

types()

Returns an object where each key is a plain joi schema type. Useful for creating type shortcuts using deconstruction. Note that the types are already formed and do not need to be called as functions (e.g. string, not string()).

const Joi = require('@hapi/joi');
const { object, string } = Joi.types();

const schema = object.keys({
  property: string.min(4)
});

any

Generates a schema object that matches any data type.

const any = Joi.any();
await any.validateAsync('a');

any.type

Gets the type of the schema.

const schema = Joi.string();

schema.type === 'string';   // === true

any.allow(...values)

Allows values where:

  • values - one or more allowed values which can be of any type and will be matched against the validated value before applying any other rules. Supports references and in-references. If the first value is Joi.override, will override any previously set values.

Note that this list of allowed values is in addition to any other permitted values. To create an exclusive list of values, see any.valid(value).

const schema = {
    a: Joi.any().allow('a'),
    b: Joi.any().allow('b', 'B')
};

any.alter(targets)

Assign target alteration options to a schema that are applied when any.tailor() is called where:

  • targets - an object where each key is a target name, and each value is a function with signature function(schema) that returns a schema.
const schema = Joi.object({
    key: Joi.string()
        .alter({
            get: (schema) => schema.required(),
            post: (schema) => schema.forbidden()
        })  
});

const getSchema = schema.tailor('get');
const postSchema = schema.tailor('post');

any.cache([cache])

Adds caching to the schema which will attempt to cache the validation results (success and failures) of incoming inputs where:

  • cache - an optional cache implementation compatible with the built-in cache provided by cache.provision(). If no cache is passed, a default cache is provisioned by using cache.provision() internally.

Note that deciding which inputs to cache is left to the cache implementation. The built-in cache will only store simple values such as undefined, null, strings, numbers, and booleans. Any changes to the schema after any.cache() is called will disable caching on the resulting schema. this means that if .cache() is not the last statement in a schema definition, caching will be disabled.

To disable caching for an entire schema in runtime, pass the cache preference set to false.

Caching ignores changes to runtime preference. This means that if you run schema.validate() onces using one set of preferences, and then again using another set (for example, changing the language), the cached results will be based on the first set of preferences.

Before using caching, it is recommended to consider the performance gain as it will not speed up every schema. Schemas using .valid() list will not benefit from caching.

Caching will be ignored when the schema uses references outside of the value scope.

Cache interface

Custom cache implementation must implement the following interface:

class {
    set(key, value) {}
    get(key) { return found ? value : undefined; }
}

Note that key and value can be anything including objects, array, etc. It is recommended to limit the size of the cache when validating external data in order to prevent an attacker from increasing the process memory usage by sending large amount of different data to validate.

any.cast(to)

Casts the validated value to the specified type where:

  • to - the value target type. Each joi schema type supports its own set of cast targets:
    • 'map' - supported by the Joi.object() type, converts the result to a Map object containing the object key-value pairs.
    • 'number' - supported by Joi.boolean() and Joi.date(), converts the result to a number. For dates, number of milliseconds since the epoch and for booleans, 0 for false and 1 for true.
    • 'set' - supported by the Joi.array() type, converts the result to a Set object containing the array values.
    • 'string' - supported by Joi.binary(), Joi.boolean(), Joi.date(), and Joi.number(), converts the result to a string.

any.concat(schema)

Returns a new type that is the result of adding the rules of one type to another where:

  • schema - a joi type to merge into the current schema. Can only be of the same type as the context type or any. If applied to an any type, the schema can be any other schema.
const a = Joi.string().valid('a');
const b = Joi.string().valid('b');
const ab = a.concat(b);

any.custom(method, [description])

Adds a custom validation function to execute arbitrary code where:

  • method - the custom validation function using signature function(value, helpers) where:
    • value - the value being validated.
    • helpers - an object with the following helpers:
      • schema - the current schema.
      • state - the current validation state.
      • prefs - the current preferences.
      • original - the original value passed into validation before any conversions.
      • error(code, [local]) - a method to generate error codes using a message code and optional local context.
      • message(messages, [local]) - a method to generate an error with an internal 'custom' error code and the provided messages object to use as override. Note that this is much slower than using the preferences messages option but is much simpler to write when performance is not important.
      • warn(code, [local]) - a method to add a warning using a message code and optional local context.

Note: if the method fails to return a value, the value will be unset or returned as undefined.

const method = (value, helpers) => {

    // Throw an error (will be replaced with 'any.custom' error)
    if (value === '1') {
        throw new Error('nope');
    }

    // Replace value with a new value
    if (value === '2') {
        return '3';
    }

    // Use error to return an existing error code
    if (value === '4') {
        return helpers.error('any.invalid');
    }

    // Override value with undefined to unset
    if (value === '5') {
        return undefined;
    }

    // Return the value unchanged
    return value;
};

const schema = Joi.string().custom(method, 'custom validation');

Possible validation errors: any.custom

any.default([value])

Sets a default value if the original value is undefined where:

  • value - the default value. One of:
    • a literal value (string, number, object, etc.).
    • a references.
    • a function which returns the default value using the signature function(parent, helpers) where:
      • parent - a clone of the object containing the value being validated. Note that since specifying a parent argument performs cloning, do not declare format arguments if you are not using them.
      • helpers - same as those described in any.custom().

When called without any value on an object schema type, a default value will be automatically generated based on the default values of the object keys.

Note that if value is an object, any changes to the object after default() is called will change the reference and any future assignment. Use a function when setting a dynamic value (e.g. the current time).

const generateUsername = (parent, helpers) => {

  return parent.firstname.toLowerCase() + '-' + parent.lastname.toLowerCase();
};

generateUsername.description = 'generated username';

const schema = Joi.object({
    username: Joi.string().default(generateUsername),
    firstname: Joi.string(),
    lastname: Joi.string(),
    created: Joi.date().default(Date.now),
    status: Joi.string().default('registered')
});

const { value } = schema.validate({
    firstname: 'Jane',
    lastname: 'Doe'
});

// value.status === 'registered'
// value.username === 'jane-doe'
// value.created will be the time of validation

Possible validation errors: any.default

any.describe()

Returns an object that represents the internal configuration of the schema. Useful for debugging and exposing a schema's configuration to other systems, like valid values in a user interface.

const schema = Joi.any().valid([ 'foo', 'bar' ]);
console.log(schema.describe());

Results in:

{ type: 'any',
  flags: { only: true },
  valids: [ 'foo', 'bar' ] }

any.description(desc)

Annotates the key where:

  • desc - the description string.
const schema = Joi.any().description('this key will match anything you give it');

any.empty(schema)

Considers anything that matches the schema to be empty (undefined).

  • schema - any object or joi schema to match. An undefined schema unsets that rule.
let schema = Joi.string().empty('');
schema.validate(''); // returns { error: null, value: undefined }
schema = schema.empty();
schema.validate(''); // returns { error: "value" is not allowed to be empty, value: '' }

any.error(err)

Overrides the default joi error with a custom error if the rule fails where:

  • err can be:
    • an instance of Error - the override error.
    • a function with the signature function(errors), where errors is an array of validation reports and it returns either a single Error or an array of validation reports.

Do not use this method if you are simply trying to override the error message - use any.message() or any.messages() instead. This method is designed to override the joi validation error and return the exact override provided. It is useful when you want to return the result of validation directly (e.g. when using with a hapi server) and want to return a different HTTP error code than 400.

Note that if you provide an Error, it will be returned as-is, unmodified and undecorated with any of the normal error properties. If validation fails and another error is found before the error override, that error will be returned and the override will be ignored (unless the abortEarly option has been set to false). If you set multiple errors on a single schema, only the last error is used.

const schema = Joi.string().error(new Error('Was REALLY expecting a string'));
schema.validate(3);     // returns Error('Was REALLY expecting a string')
const schema = Joi.object({
    foo: Joi.number().min(0).error((errors) => new Error('"foo" requires a positive number'))
});
schema.validate({ foo: -2 });    // returns new Error('"foo" requires a positive number')
const schema = Joi.object({
    foo: Joi.number().min(0).error((errors) => {

        return new Error('found errors with ' + errors.map((err) => `${err.type}(${err.local.limit}) with value ${err.local.value}`).join(' and '));
    })
});
schema.validate({ foo: -2 });    // returns new Error('child "foo" fails because [found errors with number.min(0) with value -2]')

any.example(example, [options])

Adds examples to the schema where:

  • example - adds an example. Note that no validation is performed on the value.
  • options - optional settings:
    • override - if true, replaces any existing examples. Defaults to false.
const schema = Joi.string().min(4).example('abcd');

any.external(method, [description])

Adds an external validation rule where:

  • method - an async or sync function with signature function(value) which can either return a replacement value, undefined to indicate not change, or throw an error.
  • description - optional string used to document the purpose of the method.

Note that external validation rules are only called after the all other validation rules for the entire schema (from the value root) are checked. This means that any changes made to the value by the external rules are not available to any other validation rules during the non-external validation phase.

If schema validation failed, no external validation rules are called.

any.extract(path)

Returns a sub-schema based on a path of object keys or schema ids where:

  • path - a dot . separated path string or a pre-split array of path keys. The keys must match the sub-schema id or object key (if no id was explicitly set).
const schema = Joi.object({ foo: Joi.object({ bar: Joi.number() }) });
const number = schema.extract('foo.bar');

//or
const result = schema.extract(['foo', 'bar']); //same as number

any.failover(value)

Sets a failover value if the original value fails passing validation where:

  • value - the failover value. value supports references. value may be assigned a function which returns the default value. If value is specified as a function that accepts a single parameter, that parameter will be a context object that can be used to derive the resulting value.

Note that if value is an object, any changes to the object after failover() is called will change the reference and any future assignment. Use a function when setting a dynamic value (e.g. the current time).

Using a function with a single argument performs some internal cloning which has a performance impact. If you do not need access to the context, define the function without any arguments.

Possible validation errors: any.failover

any.forbidden()

Marks a key as forbidden which will not allow any value except undefined. Used to explicitly forbid keys.

const schema = {
    a: Joi.any().forbidden()
};

Possible validation errors: any.unknown

any.fork(paths, adjuster)

Returns a new schema where each of the path keys listed have been modified where:

  • paths - an array of key strings, a single key string, or an array of arrays of pre-split key strings. Key string paths use dot . to indicate key hierarchy.
  • adjuster - a function using the signature function(schema) which must return a modified schema. For example, (schema) => schema.required().

The method does not modify the original schema.

any.id(id)

Sets a schema id for reaching into the schema via any.extract() where:

  • id - an alphanumeric string (plus _) used to identify the schema.

If no id is set, the schema id defaults to the object key it is associated with. If the schema is used in an array or alternatives type and no id is set, the schema in unreachable.

any.invalid(...values) - aliases: disallow, not

Disallows values where:

  • values - the forbidden values which can be of any type and will be matched against the validated value before applying any other rules. Supports references and in-references. If the first value is Joi.override, will override any previously set values.
const schema = {
    a: Joi.any().invalid('a'),
    b: Joi.any().invalid('b', 'B')
};

Possible validation errors: any.invalid

any.keep()

Same as rule({ keep: true }).

Note that keep() will terminate the current ruleset and cannot be followed by another rule option. Use rule() to apply multiple rule options.

any.label(name)

Overrides the key name in error messages.

  • name - the name of the key.
const schema = {
    first_name: Joi.string().label('First Name')
};

any.message(message)

Same as rule({ message }).

Note that message() will terminate the current ruleset and cannot be followed by another rule option. Use rule() to apply multiple rule options.

any.messages(messages)

Same as any.prefs({ messages }).

Note that while any.message() applies only to the last rule or ruleset, any.messages() applies to the entire schema.

any.meta(meta)

Attaches metadata to the key where:

  • meta - the meta object to attach.
const schema = Joi.any().meta({ index: true });

any.note(...notes)

Annotates the key where:

  • notes - the note string or multiple notes as individual arguments.
const schema = Joi.any().note('this is special', 'this is important');

any.only()

Requires the validated value to match of the provided any.allow() values. It has not effect when called together with any.valid() since it already sets the requirements. When used with any.allow() it converts it to an any.valid().

any.optional()

Marks a key as optional which will allow undefined as values. Used to annotate the schema for readability as all keys are optional by default.

Note: this does not allow a null value. To do that, use any.allow(value). Or both!

const schema = Joi.any().optional();

any.prefs(options) - aliases: preferences, options

Overrides the global validate() options for the current key and any sub-key where:

const schema = Joi.any().prefs({ convert: false });

any.presence(mode)

Sets the presence mode for the schema where:

  • mode - can be one of 'optional', 'required', or 'forbidden'

Same as calling any.optional(), any.required(), or any.forbidden().

any.raw([enabled])

Outputs the original untouched value instead of the casted value where:

  • enabled - if true, the original result is returned, otherwise the validated value. Defaults to true.

Note that the raw value is only applied after validation and any references to the value use the validated value, not the raw value.

const timestampSchema = Joi.date().timestamp();
timestampSchema.validate('12376834097810'); // { error: null, value: Sat Mar 17 2362 04:28:17 GMT-0500 (CDT) }

const rawTimestampSchema = Joi.date().timestamp().raw();
rawTimestampSchema.validate('12376834097810'); // { error: null, value: '12376834097810' }

any.required() - aliases: exist

Marks a key as required which will not allow undefined as value. All keys are optional by default.

const schema = Joi.any().required();

Possible validation errors: any.required

any.result(mode)

Set the result mode where:

  • mode - one of 'raw' (same as any.raw()) or 'strip' (same as any.strip()).

any.rule(options)

Applies a set of rule options to the current ruleset or last rule added where:

  • options - the rules to apply where:
    • keep - if true, the rules will not be replaced by the same unique rule later. For example, Joi.number().min(1).rule({ keep: true }).min(2) will keep both min() rules instead of the later rule overriding the first. Defaults to false.
    • message - a single message string or a messages object where each key is an error code and corresponding message string as value. The object is the same as the messages used as an option in any.validate(). The strings can be plain messages or a message template.
    • warn - if true, turns any error generated by the ruleset to warnings.

When applying rule options, the last rule (e.g. min()) is used unless there is an active ruleset defined (e.g. $.min().max()) in which case the options are applied to all the provided rules. Once rule() is called, the previous rules can no longer be modified and any active ruleset is terminated.

Rule modifications can only be applied to supported rules. Most of the any methods do not support rule modifications because they are implemented using schema flags (e.g. required()) or special internal implementation (e.g. valid()). In those cases, use the any.messages() method to override the error codes for the errors you want to customize.

any.ruleset - aliases: $

Starts a ruleset in order to apply multiple rule options. The set ends when rule(), keep(), message(), or warn() is called.

const schema = Joi.number().ruleset.min(1).max(10).rule({ message: 'Number must be between 1 and 10' });
const schema = Joi.number().$.min(1).max(10).rule({ message: 'Number must be between 1 and 10' });

any.shared(schema)

Registers a schema to be used by decendents of the current schema in named link references, where:

  • schema - a joi schema with an id.
  const schema = Joi.object({
      a: [Joi.string(), Joi.link('#x')],
      b: Joi.link('#type.a')
  })
      .shared(Joi.number().id('x'))
      .id('type');

any.strict(isStrict)

Strict mode sets the options.convert options to false which prevent type casting for the current key and any child keys.

  • isStrict - whether strict mode is enabled or not. Defaults to true.
const schema = Joi.any().strict();

any.strip([enabled])

Marks a key to be removed from a resulting object or array after validation to sanitize the output where:

  • enabled - if true, the value is stripped, otherwise the validated value is retained. Defaults to true.
const schema = Joi.object({
    username: Joi.string(),
    password: Joi.string().strip()
});

schema.validate({ username: 'test', password: 'hunter2' }); // result.value = { username: 'test' }

const schema = Joi.array().items(Joi.string(), Joi.any().strip());

schema.validate(['one', 'two', true, false, 1, 2]); // result.value = ['one', 'two']

any.tag(...tags)

Annotates the key where:

  • tags - the tag string or multiple tags (each as an argument).
const schema = Joi.any().tag('api', 'user');

any.tailor(targets)

Applies any assigned target alterations to a copy of the schema that were applied via any.alter() where:

  • targets - a single target string or array or target strings to apply.
const schema = Joi.object({
    key: Joi.string()
        .alter({
            get: (schema) => schema.required(),
            post: (schema) => schema.forbidden()
        })  
});

const getSchema = schema.tailor('get');
const postSchema = schema.tailor(['post']);

any.unit(name)

Annotates the key where:

  • name - the unit name of the value.
const schema = Joi.number().unit('milliseconds');

any.valid(...values) - aliases: equal

Adds the provided values into the allowed values list and marks them as the only valid values allowed where:

  • values - one or more allowed values which can be of any type and will be matched against the validated value before applying any other rules. Supports references and in-references. If the first value is Joi.override, will override any previously set values. If the only value is Joi.override, will also remove the only flag from the schema.
const schema = {
    a: Joi.any().valid('a'),
    b: Joi.any().valid('b', 'B')
};

Possible validation errors: any.only

any.validate(value, [options])

Validates a value using the current schema and options where:

  • value - the value being validated.
  • options - an optional object with the following optional keys:
    • abortEarly - when true, stops validation on the first error, otherwise returns all the errors found. Defaults to true.
    • allowUnknown - when true, allows object to contain unknown keys which are ignored. Defaults to false.
    • cache - when true, schema caching is enabled (for schemas with explicit caching rules). Default to true.
    • context - provides an external data set to be used in references. Can only be set as an external option to validate() and not using any.prefs().
    • convert - when true, attempts to cast values to the required types (e.g. a string to a number). Defaults to true.
    • dateFormat - sets the string format used when converting dates to strings in error messages and casting. Options are:
      • 'date' - date string.
      • 'iso' - date time ISO string. This is the default.
      • 'string' - JS default date time string.
      • 'time' - time string.
      • 'utc' - UTC date time string.
    • debug - when true, valid results and throw errors are decorated with a debug property which includes an array of the validation steps used to generate the returned result. Defaults to false.
    • errors - error formatting settings:
      • escapeHtml - when true, error message templates will escape special characters to HTML entities, for security purposes. Defaults to false.
      • label - defines the value used to set the label context variable:
        • 'path' - the full path to the value being validated. This is the default value.
        • 'key' - the key of the value being validated.
        • false - remove any label prefix from error message, including the "".
      • language - the preferred language code for error messages. The value is matched against keys at the root of the messages object, and then the error code as a child key of that. Can be a reference to the value, global context, or local context which is the root value passed to the validation function. Note that references to the value are usually not what you want as they move around the value structure relative to where the error happens. Instead, either use the global context, or the absolute value (e.g. Joi.ref('/variable'));
      • render - when false, skips rendering error templates. Useful when error messages are generated elsewhere to save processing time. Defaults to true.
      • stack - when true, the main error will possess a stack trace, otherwise it will be disabled. Defaults to false for performances reasons. Has no effect on platforms other than V8/node.js as it uses the Stack trace API.
      • wrap - overrides the way values are wrapped (e.g. [] around arrays, "" around labels). Each key can be set to a string with one (same character before and after the value) or two characters (first character before and second character after), or false to disable wrapping:
        • label - the characters used around {#label} references. Defaults to '"'.
        • array - the characters used around array values. Defaults to '[]'.
      • wrapArrays - if true, array values in error messages are wrapped in []. Defaults to true.
    • externals - if false, the external rules set with any.external() are ignored, which is required to ignore any external validations in synchronous mode (or an exception is thrown). Defaults to true.
    • messages - overrides individual error messages. Defaults to no override ({}). Messages use the same rules as templates. Variables in double braces {{var}} are HTML escaped if the option errors.escapeHtml is set to true.
    • noDefaults - when true, do not apply default values. Defaults to false.
    • nonEnumerables - when true, inputs are shallow cloned to include non-enumerables properties. Defaults to false.
    • presence - sets the default presence requirements. Supported modes: 'optional', 'required', and 'forbidden'. Defaults to 'optional'.
    • skipFunctions - when true, ignores unknown keys with a function value. Defaults to false.
    • stripUnknown - remove unknown elements from objects and arrays. Defaults to false.
      • when an object :
        • arrays - set to true to remove unknown items from arrays.
        • objects - set to true to remove unknown keys from objects.
      • when true, it is equivalent to having { arrays: false, objects: true }.

Returns an object with the following keys:

  • value - the validated and normalized value.
  • error - the validation errors if found.
  • warning - the generated warnings if any.
const schema = Joi.object({
    a: Joi.number()
});

const value = {
    a: '123'
};

const result = schema.validate(value);
// result -> { value: { "a" : 123 } }

any.validateAsync(value, [options])

Validates a value asynchronously using the current schema and options where:

  • value - the value being validated.
  • options - an optional object as described in any.validate(), with the following additional settings:
    • warnings - when true, warnings are returned alongside the value (i.e. { value, warning }). Defaults to false.

Returns a Promise that resolves into the validated value when the value is valid. If the value is valid and the warnings or debug options are set to true, returns an object { value, warning, debug }. If validation fails, the promise rejects with the validation error.

const schema = Joi.object({
    a: Joi.number()
});

const value = {
    a: '123'
};

try {
  const value = await schema.validateAsync(value);
  // value -> { "a" : 123 }
}
catch (err) {
}

any.warn()

Same as rule({ warn: true }).

Note that warn() will terminate the current ruleset and cannot be followed by another rule option. Use rule() to apply multiple rule options.

any.warning(code, [context])

Generates a warning where:

  • code - the warning code. Can be an existing error code or a custom code. If a custom code is used, a matching error message definition must be configured via any.message(), any.prefs(), or validation messages option.
  • context - optional context object.

When calling any.validateAsync(), set the warning option to true to enable warnings. Warnings are reported separately from errors alongside the result value via the warning key (i.e. { value, warning }). Warning are always included when calling any.validate().

const schema = Joi.any()
    .warning('custom.x', { w: 'world' })
    .message({ 'custom.x': 'hello {#w}!' });

const { value, error, warning } = schema.validate('anything');

// value -> 'anything';
// error -> null
// warning -> { message: 'hello world!', details: [...] }

// or

try {
    const { value, warning } = await schema.validateAsync('anything', { warnings: true });
    // value -> 'anything';
    // warning -> { message: 'hello world!', details: [...] }
}
catch (err) { }

any.when([condition], options)

Adds conditions that are evaluated during validation and modify the schema before it is applied to the value, where:

  • condition - a key name, reference, or a schema. If omitted, defaults to Joi.ref('.').
  • options - an object with:
    • is - the condition expressed as a joi schema. Anything that is not a joi schema will be converted using Joi.compile. By default, the is condition schema allows for undefined values. Use .required() to override. For example, use is: Joi.number().required() to guarantee that a joi reference exists and is a number.
    • not - the negative version of is (then and otherwise have reverse roles).
    • then - if the condition is true, the joi schema to use.
    • otherwise - if the condition is false, the joi schema to use.
    • switch - an array of { is, then } conditions that are evaluated against the condition. The last item in the array may also contain otherwise.
    • break - stops processing all other conditions if the rule results in a then, otherwise, of switch match.

If condition is a reference:

  • if is, not, and switch are missing, is defaults to Joi.invalid(null, false, 0, '').required() (value must be a truthy).
  • is and not cannot be used together.
  • one of then, otherwise, or switch is required.
  • cannot use is or then with switch.
  • cannot specify otherwise both inside the last switch statement and outside.

If condition is a schema:

  • cannot specify is or switch.
  • one of then or otherwise is required.

When is, then, or otherwise are assigned literal values, the values are compiled into override schemas ('x' is compiled into Joi.valid(Joi.override, 'x')). This means they will override any base schema the rule is applied to. To append a literal value, use the explicit Joi.valid('x') format.

Notes:

  • an invalid combination of schema modifications (e.g. trying to add string rules or a number type) will cause validation to throw an error.
  • because the schema is constructed at validation time, it can have a significant performance impact. Run-time generated schemas are cached, but the first time of each generation will take longer than once it is cached.
const schema = {
    a: Joi.any()
        .valid('x')
        .when('b', { is: Joi.exist(), then: Joi.valid('y'), otherwise: Joi.valid('z') })
        .when('c', { is: Joi.number().min(10), then: Joi.forbidden() }),
    b: Joi.any(),
    c: Joi.number()
};

Or with a schema:

const schema = Joi.object({
    a: Joi.any().valid('x'),
    b: Joi.any()
})
    .when(Joi.object({ b: Joi.exist() }).unknown(), {
        then: Joi.object({
            a: Joi.valid('y')
        }),
        otherwise: Joi.object({
            a: Joi.valid('z')
        })
});

Note that this style is much more useful when your whole schema depends on the value of one of its property, or if you find yourself repeating the check for many keys of an object. For example to validate this logic:

const schema = Joi.object({
    type: Joi.string()
        .valid('A', 'B', 'C')
        .required(),              // required if type == 'A'
        
    foo: Joi.when('type', {
        is: 'A',
        then: Joi.string()
        .valid('X', 'Y', 'Z')
        .required()
    }),                           // required if type === 'A' and foo !== 'Z'
    
    bar: Joi.string()
})
    .when(Joi.object({ type: Joi.valid('A'), foo: Joi.not('Z') }).unknown(), {
        then: Joi.object({ bar: Joi.required() })
    });

Alternatively, if you want to specify a specific type such as string, array, etc, you can do so like this:

const schema = {
    a: Joi.valid('a', 'b', 'other'),
    other: Joi.string()
        .when('a', { is: 'other', then: Joi.required() }),
};

If you need to validate a child key inside a nested object based on a sibling's value, you can do so like this:

const schema = Joi.object({
    a: Joi.boolean().required(),
    b: Joi.object()
        .keys({
            c: Joi.string(),
            d: Joi.number().required()
        })
        .required()
        .when('a', {
            is: true,
            then: Joi.object({ c: Joi.required() })		// b.c is required only when a is true
        })
});

If you want to validate one key based on the existence of another key, you can do so like the following (notice the use of required()):

const schema = Joi.object({
    min: Joi.number(),
    max: Joi.number().when('min', {
        is: Joi.number().required(),
        then: Joi.number().greater(Joi.ref('min')),
    }),
});

To evaluate multiple values on a single reference:

const schema = Joi.object({
    a: Joi.number().required(),
    b: Joi.number()
        .when('a', {
            switch: [
                { is: 0, then: Joi.valid(1) },
                { is: 1, then: Joi.valid(2) },
                { is: 2, then: Joi.valid(3) }
            ],
            otherwise: Joi.valid(4)
        })
});

Or shorter:

const schema = Joi.object({
    a: Joi.number().required(),
    b: Joi.number()
        .when('a', [
            { is: 0, then: 1 },
            { is: 1, then: 2 },
            { is: 2, then: 3, otherwise: 4 }
        ])
});

alternatives

Generates a type that will match one of the provided alternative schemas via the try() method. If no schemas are added, the type will not match any value except for undefined.

Supports the same methods of the any() type.

Alternatives can be expressed using the shorter [] notation.

const alt = Joi.alternatives().try(Joi.number(), Joi.string());
// Same as [Joi.number(), Joi.string()]

Possible validation errors: alternatives.any, alternatives.all, alternatives.one, alternatives.types, alternatives.match

alternatives.conditional(condition, options)

Adds a conditional alternative schema type, either based on another key value, or a schema peeking into the current value, where:

  • condition - the key name or reference, or a schema.
  • options - an object with:
    • is - the condition expressed as a joi schema. Anything that is not a joi schema will be converted using Joi.compile.
    • not - the negative version of is (then and otherwise have reverse roles).
    • then - if the condition is true, the joi schema to use.
    • otherwise - if the condition is false, the joi schema to use.
    • switch - an array of { is, then } conditions that are evaluated against the condition. The last item in the array may also contain otherwise.

If condition is a reference:

  • if is, not, and switch are missing, is defaults to Joi.invalid(null, false, 0, '').required() (value must be a truthy).
  • is and not cannot be used together.
  • one of then, otherwise, or switch is required.
  • cannot use is or then with switch.
  • cannot specify otherwise both inside the last switch statement and outside.

If condition is a schema:

  • cannot specify is or switch.
  • one of then or otherwise is required.

When is, then, or otherwise are assigned literal values, the values are compiled into override schemas ('x' is compiled into Joi.valid(Joi.override, 'x')). This means they will override any base schema the rule is applied to. To append a literal value, use the explicit Joi.valid('x') format.

Note that alternatives.conditional() is different than any.when(). When you use any.when() you end up with composite schema of all the matching conditions while alternatives.conditional() will use the first matching schema, ignoring other conditional statements.

const schema = {
    a: Joi.alternatives().conditional('b', { is: 5, then: Joi.string(), otherwise: Joi.number() }),
    b: Joi.any()
};
const schema = Joi.alternatives().conditional(Joi.object({ b: 5 }).unknown(), {
    then: Joi.object({
        a: Joi.string(),
        b: Joi.any()
    }),
    otherwise: Joi.object({
        a: Joi.number(),
        b: Joi.any()
    })
});

Note that conditional() only adds additional alternatives to try and does not impact the overall type. Setting a required() rule on a single alternative will not apply to the overall key. For example, this definition of a:

const schema = {
    a: Joi.alternatives().conditional('b', { is: true, then: Joi.required() }),
    b: Joi.boolean()
};

Does not turn a into a required key when b is true. Instead, it tells the validator to try and match the value to anything that's not undefined. However, since Joi.alternatives() by itself allows undefined, the rule does not accomplish turning a to a required value. This rule is the same as Joi.alternatives([Joi.required()]) when b is true which will allow any value including undefined.

To accomplish the desired result above use:

const schema = {
    a: Joi.when('b', { is: true, then: Joi.required() }),
    b: Joi.boolean()
};

alternatives.match(mode)

Requires the validated value to match a specific set of the provided alternative.try() schemas where:

  • mode - the match mode which can be one of:
    • 'any' - match any provided schema. This is the default value.
    • 'all' - match all of the provided schemas. Note that this will ignore any conversions performed by the matchin schemas and return the raw value provided regardless of the convert preference set.
    • 'one' - match one and only one of the provided schemas.

Note: Cannot be combined with alternatives.conditional().

Possible validation errors: alternatives.any, alternatives.all, alternatives.one

alternatives.try(...schemas)

Adds an alternative schema type for attempting to match against the validated value where:

  • schemas - alternative joi types, each as a separate argument.
const alt = Joi.alternatives().try(Joi.number(), Joi.string());
await alt.validateAsync('a');

array

Generates a schema object that matches an array data type. Note that undefined values inside arrays are not allowed by default but can be by using sparse().

Supports the same methods of the any() type.

const array = Joi.array().items(Joi.string().valid('a', 'b'));
await array.validateAsync(['a', 'b', 'a']);

Possible validation errors: array.base

array.has(schema)

Verifies that a schema validates at least one of the values in the array, where:

  • schema - the validation rules required to satisfy the check. If the schema includes references, they are resolved against the array item being tested, not the value of the ref target.
const schema = Joi.array().items(
  Joi.object({
    a: Joi.string(),
    b: Joi.number()
  })
).has(Joi.object({ a: Joi.string().valid('a'), b: Joi.number() }))

Possible validation errors: array.hasKnown, array.hasUnknown

array.items(...types)

Lists the types allowed for the array values where:

  • types - one or more joi schema objects to validate each array item against.

If a given type is .required() then there must be a matching item in the array. If a type is .forbidden() then it cannot appear in the array. Required items can be added multiple times to signify that multiple items must be found. Errors will contain the number of items that didn't match. Any unmatched item having a label will be mentioned explicitly.

const schema = Joi.array().items(Joi.string(), Joi.number()); // array may contain strings and numbers
const schema = Joi.array().items(Joi.string().required(), Joi.string().required()); // array must contain at least two strings
const schema = Joi.array().items(Joi.string().valid('not allowed').forbidden(), Joi.string()); // array may contain strings, but none of those strings can match 'not allowed'
const schema = Joi.array().items(Joi.string().label('My string').required(), Joi.number().required()); // If this fails it can result in `[ValidationError: "value" does not contain [My string] and 1 other required value(s)]`

Possible validation errors: array.excludes, [array.includesRequiredBoth], [array.includesRequiredKnowns], [array.includesRequiredUnknowns], array.includes

array.length(limit)

Specifies the exact number of items in the array where:

  • limit - the number of array items allowed or a reference.
const schema = Joi.array().length(5);
const schema = Joi.object({
  limit: Joi.number().integer().required(),
  numbers: Joi.array().length(Joi.ref('limit')).required()
});

Possible validation errors: array.length, array.ref

array.max(limit)

Specifies the maximum number of items in the array where:

  • limit - the highest number of array items allowed or a reference.
const schema = Joi.array().max(10);
const schema = Joi.object({
  limit: Joi.number().integer().required(),
  numbers: Joi.array().max(Joi.ref('limit')).required()
});

Possible validation errors: array.max, array.ref

array.min(limit)

Specifies the minimum number of items in the array where:

  • limit - the lowest number of array items allowed or a reference.
const schema = Joi.array().min(2);
const schema = Joi.object({
  limit: Joi.number().integer().required(),
  numbers: Joi.array().min(Joi.ref('limit')).required()
});

Possible validation errors: array.min, array.ref

array.ordered(...type)

Lists the types in sequence order for the array values where:

  • types - one or more joi schema objects to validate against each array item in sequence order.

If a given type is .required() then there must be a matching item with the same index position in the array. Errors will contain the number of items that didn't match. Any unmatched item having a label will be mentioned explicitly.

const schema = Joi.array().ordered(Joi.string().required(), Joi.number().required()); // array must have first item as string and second item as number
const schema = Joi.array().ordered(Joi.string().required()).items(Joi.number().required()); // array must have first item as string and 1 or more subsequent items as number
const schema = Joi.array().ordered(Joi.string().required(), Joi.number()); // array must have first item as string and optionally second item as number

Possible validation errors: array.excludes, array.includes, array.orderedLength

array.single([enabled])

Allows single values to be checked against rules as if it were provided as an array.

enabled can be used with a falsy value to go back to the default behavior.

const schema = Joi.array().items(Joi.number()).single();
schema.validate([4]); // returns `{ error: null, value: [ 4 ] }`
schema.validate(4); // returns `{ error: null, value: [ 4 ] }`

Possible validation errors: array.excludes, array.includes

array.sort([options])

Requires the array to comply with the specified sort order where:

  • options - optional settings:
    • order - the sort order. Allowed values:
      • 'ascending' - sort the array in ascending order. This is the default.
      • 'descending' - sort the array in descending order.
    • by - a key name or reference to sort array objects by. Defaults to the entire value.

Notes:

  • if the convert preference is true, the array is modified to match the required sort order.
  • undefined values are always placed at the end of the array regardless of the sort order.
  • can only sort string and number items or item key values.

Possible validation errors: array.sort, array.sort.unsupported, array.sort.mismatching

array.sparse([enabled])

Allows this array to be sparse. enabled can be used with a falsy value to go back to the default behavior.

let schema = Joi.array().sparse(); // undefined values are now allowed
schema = schema.sparse(false); // undefined values are now denied

Possible validation errors: array.sparse

array.unique([comparator, [options]])

Requires the array values to be unique where:

  • comparator - an optional custom comparator that is either:
    • a function that takes 2 parameters to compare. This function should return whether the 2 parameters are equal or not, you are also responsible for this function not to fail, any Error would bubble out of Joi.
    • a string in dot notation representing the path of the element to do uniqueness check on. Any missing path will be considered undefined, and can as well only exist once.
  • options - optional settings:
    • ignoreUndefined - if true, undefined values for the dot notation string comparator will not cause the array to fail on uniqueness. Defaults to false.
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.

Note: remember that if you provide a custom comparator function, different types can be passed as parameter depending on the rules you set on items.

Be aware that a deep equality is performed on elements of the array having a type of object, a performance penalty is to be expected for this kind of operation.

const schema = Joi.array().unique();
const schema = Joi.array().unique((a, b) => a.property === b.property);
const schema = Joi.array().unique('customer.id');
let schema = Joi.array().unique('identifier');

schema.validate([{}, {}]);
// ValidationError: "value" position 1 contains a duplicate value

schema = Joi.array().unique('identifier', { ignoreUndefined: true });

schema.validate([{}, {}]);
// error: null

Possible validation errors: array.unique

binary

Generates a schema object that matches a Buffer data type. If the validation convert option is on (enabled by default), a string will be converted to a Buffer if specified.

Supports the same methods of the any() type.

const schema = Joi.binary();

Possible validation errors: binary.base

binary.encoding(encoding)

Sets the string encoding format if a string input is converted to a buffer where:

  • encoding - the encoding scheme.
const schema = Joi.binary().encoding('base64');

binary.length(limit)

Specifies the exact length of the buffer:

  • limit - the size of buffer allowed or a reference.
const schema = Joi.binary().length(5);

Possible validation errors: binary.length, binary.ref

binary.max(limit)

Specifies the maximum length of the buffer where:

  • limit - the highest size of the buffer or a reference.
const schema = Joi.binary().max(10);

Possible validation errors: binary.max, binary.ref

binary.min(limit)

Specifies the minimum length of the buffer where:

  • limit - the lowest size of the buffer or a reference.
const schema = Joi.binary().min(2);

Possible validation errors: binary.min, binary.ref

boolean

Generates a schema object that matches a boolean data type. Can also be called via bool(). If the validation convert option is on (enabled by default), a string (either "true" or "false") will be converted to a boolean if specified.

Supports the same methods of the any() type.

const boolean = Joi.boolean();

await boolean.validateAsync(true); // Valid
await boolean.validateAsync(1);    // Throws

Possible validation errors: boolean.base

boolean.falsy(...values)

Allows for additional values to be considered valid booleans by converting them to false during validation. Requires the validation convert option to be true.

String comparisons are by default case insensitive, see boolean.sensitive() to change this behavior.

const boolean = Joi.boolean().falsy('N');
await boolean.validateAsync('N'); // Valid

boolean.sensitive([enabled])

Restrict the values provided to truthy and falsy as well as the 'true' and 'false' default conversions (when not in strict() mode) to be matched in a case sensitive manner, where:

  • enabled - when false, allows insensitive comparison. Defaults to true.
const schema = Joi.boolean().truthy('yes').falsy('no').sensitive();

boolean.truthy(...values)

Allows for additional values to be considered valid booleans by converting them to true during validation. Requires the validation convert option to be true.

String comparisons are by default case insensitive, see boolean.sensitive() to change this behavior.

const boolean = Joi.boolean().truthy('Y');
await boolean.validateAsync('Y'); // Valid

date

Generates a schema object that matches a date type (as well as a JavaScript date string or number of milliseconds). If the validation convert option is on (enabled by default), a string or number will be converted to a Date if specified.

Supports the same methods of the any() type.

const date = Joi.date();
await date.validateAsync('12-21-2012');

Possible validation errors: date.base, date.strict

date.greater(date)

Specifies that the value must be greater than date (or a reference).

const schema = Joi.date().greater('1-1-1974');

Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.

const schema = Joi.date().greater('now');
const schema = Joi.object({
  from: Joi.date().required(),
  to: Joi.date().greater(Joi.ref('from')).required()
});

Possible validation errors: date.greater, date.ref

date.iso()

Requires the string value to be in valid ISO 8601 date format.

const schema = Joi.date().iso();

Possible validation errors: date.format

date.less(date)

Specifies that the value must be less than date (or a reference).

const schema = Joi.date().less('12-31-2020');

Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.

const schema = Joi.date().max('now');
const schema = Joi.object({
  from: Joi.date().less(Joi.ref('to')).required(),
  to: Joi.date().required()
});

Possible validation errors: date.less, date.ref

date.max(date)

Specifies the latest date allowed where:

  • date - the latest date allowed or a reference.
const schema = Joi.date().max('12-31-2020');

Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.

const schema = Joi.date().max('now');
const schema = Joi.object({
  from: Joi.date().max(Joi.ref('to')).required(),
  to: Joi.date().required()
});

Possible validation errors: date.max, date.ref

date.min(date)

Specifies the oldest date allowed where:

  • date - the oldest date allowed or a reference.
const schema = Joi.date().min('1-1-1974');

Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.

const schema = Joi.date().min('now');
const schema = Joi.object({
  from: Joi.date().required(),
  to: Joi.date().min(Joi.ref('from')).required()
});

Possible validation errors: date.min, date.ref

date.timestamp([type])

Requires the value to be a timestamp interval from Unix Time.

  • type - the type of timestamp (allowed values are unix or javascript [default])
const schema = Joi.date().timestamp(); // defaults to javascript timestamp
const schema = Joi.date().timestamp('javascript'); // also, for javascript timestamp (milliseconds)
const schema = Joi.date().timestamp('unix'); // for unix timestamp (seconds)

Possible validation errors: date.format

function - inherits from object

Generates a schema object that matches a function type.

Supports the same methods of the object() type. Note that validating a function keys will cause the function to be cloned. While the function will retain its prototype and closure, it will lose its length property value (will be set to 0).

const func = Joi.function();
await func.validateAsync(function () {});

Possible validation errors: object.base

function.arity(n)

Specifies the arity of the function where:

  • n - the arity expected.
const schema = Joi.function().arity(2);

Possible validation errors: function.arity

function.class()

Requires the function to be a class.

const schema = Joi.function().class();

Possible validation errors: function.class

function.maxArity(n)

Specifies the maximal arity of the function where:

  • n - the maximum arity expected.
const schema = Joi.function().maxArity(3);

Possible validation errors: function.maxArity

function.minArity(n)

Specifies the minimal arity of the function where:

  • n - the minimal arity expected.
const schema = Joi.function().minArity(1);

Possible validation errors: function.minArity

link(ref)

Links to another schema node and reuses it for validation, typically for creative recursive schemas, where:

  • ref - the reference to the linked schema node. Cannot reference itself or its children as well as other links. Links can be expressed in relative terms like value references (Joi.link('...')), in absolute terms from the schema run-time root (Joi.link('/a')), or using schema ids implicitly using object keys or explicitly using any.id() (Joi.link('#a.b.c')).

Supports the methods of the any() type.

When links are combined with any.when() rules, the rules are applied after the link is resolved to the linked schema.

Names links are recommended for most use cases as they are easy to reason and understand, and when mistakes are made, they simply error with invalid link message. Relative links are often hard to follow, especially when they are nested in array or alternatives rules. Absolute links are useful only when the schema is never reused inside another schema as the root is the run-time root of the schema being validated, not the current schema root.

Note that named links must be found in a direct ancestor of the link. The names are searched by iterating over the chain of schemas from the current schema to the root. To reach an uncle or cousin, you must use the name of a common ancestor such as a grandparent and then walk down the tree.

Links are resolved once (per runtime) and the result schema cached. If you reuse a link in different places, the first time it is resolved at run-time, the result will be used by all other instances. If you want each link to resolve relative to the place it is used, use a separate Joi.link() statement in each place or set the relative() flag.

Named links:

const person = Joi.object({
    firstName: Joi.string().required(),
    lastName: Joi.string().required(),
    children: Joi.array()
        .items(Joi.link('#person'))
})
  .id('person');

Relative links:

const person = Joi.object({
    firstName: Joi.string().required(),
    lastName: Joi.string().required(),
    children: Joi.array()
        .items(Joi.link('...'))
        // . - the link
        // .. - the children array
        // ... - the person object
});

Absolute links:

const person = Joi.object({
    firstName: Joi.string().required(),
    lastName: Joi.string().required(),
    children: Joi.array()
        .items(Joi.link('/'))
});

link.ref(ref)

Initializes the schema after constructions for cases where the schema has to be constructed first and then initialized. If ref was not passed to the constructor, link.ref() must be called prior to usaged.

Will throw an error during validation if left uninitialized (e.g. Joi.link() called without a link and link.ref() not called).

link.concat(schema)

Same as any.concat() but the schema is merged after the link is resolved which allows merging with schemas of the same type as the resolved link. Will throw an exception during validation if the merged types are not compatible.

number

Generates a schema object that matches a number data type (as well as strings that can be converted to numbers).

By default, it only allows safe numbers, see number.unsafe().

If the validation convert option is on (enabled by default), a string will be converted to a number if specified. Also, if convert is on and number.precision() is used, the value will be converted to the specified precision as well.

Infinity and -Infinity are invalid by default, you can change that behavior by calling allow(Infinity, -Infinity).

Supports the same methods of the any() type.

const number = Joi.number();
await number.validateAsync(5);

Possible validation errors: number.base, number.infinity

number.greater(limit)

Specifies that the value must be greater than limit or a reference.

const schema = Joi.number().greater(5);
const schema = Joi.object({
  min: Joi.number().required(),
  max: Joi.number().greater(Joi.ref('min')).required()
});

Possible validation errors: number.greater, number.ref

number.integer()

Requires the number to be an integer (no floating point).

const schema = Joi.number().integer();

Possible validation errors: number.base

number.less(limit)

Specifies that the value must be less than limit or a reference.

const schema = Joi.number().less(10);
const schema = Joi.object({
  min: Joi.number().less(Joi.ref('max')).required(),
  max: Joi.number().required()
});

Possible validation errors: number.less, number.ref

number.max(limit)

Specifies the maximum value where:

  • limit - the maximum value allowed or a reference.
const schema = Joi.number().max(10);
const schema = Joi.object({
  min: Joi.number().max(Joi.ref('max')).required(),
  max: Joi.number().required()
});

Possible validation errors: number.max, number.ref

number.min(limit)

Specifies the minimum value where:

  • limit - the minimum value allowed or a reference.
const schema = Joi.number().min(2);
const schema = Joi.object({
  min: Joi.number().required(),
  max: Joi.number().min(Joi.ref('min')).required()
});

Possible validation errors: number.min, number.ref

number.multiple(base)

Specifies that the value must be a multiple of base (or a reference):

const schema = Joi.number().multiple(3);

Notes: Joi.number.multiple(base) uses the modulo operator (%) to determine if a number is multiple of another number. Therefore, it has the normal limitations of Javascript modulo operator. The results with decimal/floats may be incorrect.

Possible validation errors: number.multiple, number.ref

number.negative()

Requires the number to be negative.

const schema = Joi.number().negative();

Possible validation errors: number.negative

number.port()

Requires the number to be a TCP port, so between 0 and 65535.

const schema = Joi.number().port();

Possible validation errors: number.port

number.positive()

Requires the number to be positive.

const schema = Joi.number().positive();

Possible validation errors: number.positive

number.precision(limit)

Specifies the maximum number of decimal places where:

  • limit - the maximum number of decimal places allowed.
const schema = Joi.number().precision(2);

Possible validation errors: number.integer

number.sign(sign)

Requires the number to be negative or positive where: sign - one of 'negative' or 'positive'.

Possible validation errors: number.negative, number.positive

number.unsafe([enabled])

By default, numbers must be within JavaScript's safety range (Number.MIN_SAFE_INTEGER & Number.MAX_SAFE_INTEGER), and when given a string, should be converted without loss of information. You can allow unsafe numbers at your own risks by calling number.unsafe().

Parameters are:

  • enabled - optional parameter defaulting to true which allows you to reset the behavior of unsafe by providing a falsy value.
const safeNumber = Joi.number();
safeNumber.validate(90071992547409924);
// error -> "value" must be a safe number

const unsafeNumber = Joi.number().unsafe();
unsafeNumber.validate(90071992547409924);
// error -> null
// value -> 90071992547409920

Possible validation errors: number.unsafe

object

Generates a schema object that matches an object data type. Defaults to allowing any child key.

Supports the same methods of the any() type.

const object = Joi.object({
    a: Joi.number().min(1).max(10).integer(),
    b: 'some string'
});

await object.validateAsync({ a: 5 });

Note that when an object schema type is passed as an input to another joi method (e.g. array item) or is set as a key definition, the Joi.object() constructor may be omitted. For example:

const schema = Joi.array().items({ a: Joi.string() });

Possible validation errors: object.base

object.and(...peers, [options])

Defines an all-or-nothing relationship between keys where if one of the peers is present, all of them are required as well where:

  • peers - the string key names of which if one present, all are required.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).and('a', 'b');

Possible validation errors: object.and

object.append([schema])

Appends the allowed object keys where:

  • schema - optional object where each key is assigned a joi type object. If schema is null,undefined or {} no changes will be applied. Uses object.keys([schema]) to append keys.
// Validate key a
const base = Joi.object({
    a: Joi.number()
});
// Validate keys a, b.
const extended = base.append({
    b: Joi.string()
});

object.assert(subject, schema, [message])

Verifies an assertion where:

  • subject - the key name, reference, or template expression to validate. Note that the reference is resolved against the object itself as value, which means if you want to reference a key of the object being validated, you have to prefix the reference path with ..
  • schema - the validation rules required to satisfy the assertion. If the schema includes references, they are resolved against the object value, not the value of the subject target.
  • message - optional human-readable message used when the assertion fails. Defaults to 'failed to pass the assertion test'.
const schema = Joi.object({
    a: {
        b: Joi.string(),
        c: Joi.number()
    },
    d: {
        e: Joi.any()
    }
}).assert('.d.e', Joi.ref('a.c'), 'equal to a.c');

Possible validation errors: object.assert

object.instance(constructor, [name])

Requires the object to be an instance of a given constructor where:

  • constructor - the constructor function that the object must be an instance of.
  • name - an alternate name to use in validation errors. This is useful when the constructor function does not have a name.
const schema = Joi.object().instance(RegExp);

Possible validation errors: object.instance

object.keys([schema])

Sets or extends the allowed object keys where:

  • schema - optional object where each key is assigned a joi type object. If schema is {} no keys allowed. If schema is null or undefined, any key allowed. If schema is an object with keys, the keys are added to any previously defined keys (but narrows the selection if all keys previously allowed). Defaults to 'undefined' which allows any child key.
const base = Joi.object().keys({
    a: Joi.number(),
    b: Joi.string()
});
// Validate keys a, b and c.
const extended = base.keys({
    c: Joi.boolean()
});

Possible validation errors: object.unknown

object.length(limit)

Specifies the exact number of keys in the object where or a reference:

  • limit - the number of object keys allowed.
const schema = Joi.object().length(5);

Possible validation errors: object.length, object.ref

object.max(limit)

Specifies the maximum number of keys in the object where:

  • limit - the highest number of object keys allowed or a reference.
const schema = Joi.object().max(10);

Possible validation errors: object.max, object.ref

object.min(limit)

Specifies the minimum number of keys in the object where:

  • limit - the lowest number of keys allowed or a reference.
const schema = Joi.object().min(2);

Possible validation errors: object.min, object.ref

object.nand(...peers, [options])

Defines a relationship between keys where not all peers can be present at the same time where:

  • peers - the key names of which if one present, the others may not all be present.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).nand('a', 'b');

Possible validation errors: object.nand

object.or(...peers, [options])

Defines a relationship between keys where one of the peers is required (and more than one is allowed) where:

  • peers - the key names of which at least one must appear.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).or('a', 'b');

Possible validation errors: object.missing

object.oxor(...peers, [options])

Defines an exclusive relationship between a set of keys where only one is allowed but none are required where:

  • peers - the exclusive key names that must not appear together but where none are required.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).oxor('a', 'b');

Possible validation errors: object.oxor

object.pattern(pattern, schema, [options])

Specify validation rules for unknown keys matching a pattern where:

  • pattern - a pattern that can be either a regular expression or a joi schema that will be tested against the unknown key names. Note that if the pattern is a regular expression, for it to match the entire key name, it must begin with ^ and end with $.
  • schema - the schema object matching keys must validate against.
  • options - options settings:
    • fallthrough - if true, multiple matching patterns are tested against the key, otherwise once a pattern match is found, no other patterns are compared. Defaults to false.
    • matches - a joi array schema used to validated the array of matching keys. For example, Joi.object().pattern(/\d/, Joi.boolean(), { matches: Joi.array().length(2) }) will require two matching keys. If the matches schema is not an array type schema, it will be converted to Joi.array().items(matches). If the matches schema contains references, they are resolved against the ancestors as follows:
      • self - the array of matching keys (Joi.ref('.length'))
      • parent - the object value containing the keys (Joi.ref('a'))
const schema = Joi.object({
    a: Joi.string()
}).pattern(/\w\d/, Joi.boolean());

// OR

const schema = Joi.object({
    a: Joi.string()
}).pattern(Joi.string().min(2).max(5), Joi.boolean());

Possible validation errors: object.pattern.match

object.ref()

Requires the object to be a joi reference.

const schema = Joi.object().ref();

Possible validation errors: object.refType

object.rename(from, to, [options])

Renames a key to another name (deletes the renamed key) where:

  • from - the original key name or a regular expression matching keys.
  • to - the new key name. to can be set to a template which is rendered at runtime using the current value, global context, and local context if from is a regular expression (e.g. the expression /^(\d+)$/ will match any all-digits keys with a capture group that is accessible in the template via {#1}).
  • options - an optional object with the following optional keys:
    • alias - if true, does not delete the old key name, keeping both the new and old keys in place. Defaults to false.
    • multiple - if true, allows renaming multiple keys to the same destination where the last rename wins. Defaults to false.
    • override - if true, allows renaming a key over an existing key. Defaults to false.
    • ignoreUndefined - if true, skip renaming of a key if it's undefined. Defaults to false.

Keys are renamed before any other validation rules are applied. If to is a template that references the object own keys (e.g. '{.prefix}-{#1}'), the value of these keys is the raw input value, not the value generated after validation.

const object = Joi.object({
    a: Joi.number()
}).rename('b', 'a');

await object.validateAsync({ b: 5 });

Using a regular expression:

const regex = /^foobar$/i;

const schema = Joi.object({
  fooBar: Joi.string()
}).rename(regex, 'fooBar');

await schema.validateAsync({ FooBar: 'a'});

Using a regular expression with template:

const schema = Joi.object()
    .rename(/^(\d+)$/, Joi.template('x{#1}x'))
    .pattern(/^x\d+x$/, Joi.any());

const input = {
    123: 'x',
    1: 'y',
    0: 'z',
    x4x: 'test'
};

const value = await Joi.compile(schema).validateAsync(input);
// value === { x123x: 'x', x1x: 'y', x0x: 'z', x4x: 'test' }

Possible validation errors: object.rename.multiple, object.rename.override

object.schema([type])

Requires the object to be a joi schema instance where:

  • type - optional joi schema to require.
const schema = Joi.object().schema();

Possible validation errors: object.schema

object.unknown([allow])

Overrides the handling of unknown keys for the scope of the current object only (does not apply to children) where:

  • allow - if false, unknown keys are not allowed, otherwise unknown keys are ignored.
const schema = Joi.object({ a: Joi.any() }).unknown();

Possible validation errors: object.unknown

object.with(key, peers, [options])

Requires the presence of other keys whenever the specified key is present where:

  • key - the reference key.
  • peers - the required peer key names that must appear together with key. peers can be a single string value or an array of string values.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.

Note that unlike object.and(), with() creates a dependency only between the key and each of the peers, not between the peers themselves.

const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).with('a', 'b');

Possible validation errors: object.with

object.without(key, peers, [options])

Forbids the presence of other keys whenever the specified is present where:

  • key - the reference key.
  • peers - the forbidden peer key names that must not appear together with key. peers can be a single string value or an array of string values.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).without('a', ['b']);

Possible validation errors: object.without

object.xor(...peers, [options])

Defines an exclusive relationship between a set of keys where one of them is required but not at the same time where:

  • peers - the exclusive key names that must not appear together but where one of them is required.
  • options - optional settings:
    • separator - overrides the default . hierarchy separator. Set to false to treat the key as a literal value.
const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).xor('a', 'b');

Possible validation errors: object.xor, object.missing

string

Generates a schema object that matches a string data type.

Note that the empty string is not allowed by default and must be enabled with allow(''). Don't over think, just remember that the empty string is not a valid string by default. Also, don't ask to change it or argue why it doesn't make sense. This topic is closed.

To specify a default value in case of the empty string use:

Joi.string()
    .empty('')
    .default('default value');

If the convert preference is true (the default value), a string will be converted using the specified modifiers for string.lowercase(), string.uppercase(), string.trim(), and each replacement specified with string.replace().

Supports the same methods of the any() type.

const schema = Joi.string().min(1).max(10);
await schema.validateAsync('12345');

Possible validation errors: string.base, string.empty

string.alphanum()

Requires the string value to only contain a-z, A-Z, and 0-9.

const schema = Joi.string().alphanum();

Possible validation errors: string.alphanum

string.base64([options])

Requires the string value to be a valid base64 string; does not check the decoded value.

  • options - optional settings:
    • paddingRequired - if true, the string must be properly padded with the = characters. Defaults to true.
    • urlSafe - if true, uses the URI-safe base64 format which replaces + with - and \ with _. Defaults to false.

Padding characters are not required for decoding, as the number of missing bytes can be inferred from the number of digits. With that said, try to use padding if at all possible.

const schema = Joi.string().base64();
schema.validate('VE9PTUFOWVNFQ1JFVFM'); // ValidationError: "value" must be a valid base64 string
schema.validate('VE9PTUFOWVNFQ1JFVFM='); // No Error

const paddingRequiredSchema = Joi.string().base64({ paddingRequired: true });
paddingRequiredSchema.validate('VE9PTUFOWVNFQ1JFVFM'); // ValidationError: "value" must be a valid base64 string
paddingRequiredSchema.validate('VE9PTUFOWVNFQ1JFVFM='); // No Error

const paddingOptionalSchema = Joi.string().base64({ paddingRequired: false });
paddingOptionalSchema.validate('VE9PTUFOWVNFQ1JFVFM'); // No Error
paddingOptionalSchema.validate('VE9PTUFOWVNFQ1JFVFM='); // No Error

Possible validation errors: string.base64

string.case(direction)

Sets the required string case where:

  • direction - can be either 'upper' or 'lower'.
const schema = Joi.string().case('lower');

Possible validation errors: string.lowercase string.uppercase

string.creditCard()

Requires the number to be a credit card number (Using Luhn Algorithm).

const schema = Joi.string().creditCard();

Possible validation errors: string.creditCard

string.dataUri([options])

Requires the string value to be a valid data URI string.

  • options - optional settings:
    • paddingRequired - optional parameter defaulting to true which will require = padding if true or make padding optional if false.
const schema = Joi.string().dataUri();
schema.validate('VE9PTUFOWVNFQ1JFVFM='); // ValidationError: "value" must be a valid dataUri string
schema.validate('data:image/png;base64,VE9PTUFOWVNFQ1JFVFM='); // No Error

Possible validation errors: string.dataUri

string.domain([options])

Requires the string value to be a valid domain name.

  • options - optional settings:
    • allowUnicode - if true, Unicode characters are permitted. Defaults to true.
    • minDomainSegments - Number of segments required for the domain. Defaults to 2.
    • tlds - options for TLD (top level domain) validation. By default, the TLD must be a valid name listed on the IANA registry. To disable validation, set tlds to false. To customize how TLDs are validated, set one of these:
      • allow - one of:
        • true to use the IANA list of registered TLDs. This is the default value.
        • false to allow any TLD not listed in the deny list, if present.
        • a Set or array of the allowed TLDs. Cannot be used together with deny.
      • deny - one of:
        • a Set or array of the forbidden TLDs. Cannot be used together with a custom allow list.
const schema = Joi.string().domain();

Possible validation errors: string.domain

string.email([options])

Requires the string value to be a valid email address.

  • options - optional settings:
    • allowUnicode - if true, Unicode characters are permitted. Defaults to true.
    • ignoreLength - if true, ignore invalid email length errors. Defaults to false.
    • minDomainSegments - Number of segments required for the domain. The default setting excludes single segment domains such as example@io which is a valid email but very uncommon. Defaults to 2.
    • multiple - if true, allows multiple email addresses in a single string, separated by , or the separator characters. Defaults to false.
    • separator - when multiple is true, overrides the default , separator. String can be a single character or multiple separator characters. Defaults to ','.
    • tlds - options for TLD (top level domain) validation. By default, the TLD must be a valid name listed on the IANA registry. To disable validation, set tlds to false. To customize how TLDs are validated, set one of these:
      • allow - one of:
        • true to use the IANA list of registered TLDs. This is the default value.
        • false to allow any TLD not listed in the deny list, if present.
        • a Set or array of the allowed TLDs. Cannot be used together with deny.
      • deny - one of:
        • a Set or array of the forbidden TLDs. Cannot be used together with a custom allow list.
const schema = Joi.string().email();

Possible validation errors: string.email

string.guid() - aliases: uuid

Requires the string value to be a valid GUID.

  • options - optional settings:
    • version - Specifies one or more acceptable versions. Can be an Array or String with the following values: uuidv1, uuidv2, uuidv3, uuidv4, or uuidv5. If no version is specified then it is assumed to be a generic guid which will not validate the version or variant of the guid and just check for general structure format.
const schema = Joi.string().guid({
    version: [
        'uuidv4',
        'uuidv5'
    ]
});

Possible validation errors: string.guid

string.hex([options])

Requires the string value to be a valid hexadecimal string.

  • options - optional settings:
    • byteAligned - Boolean specifying whether you want to check that the hexadecimal string is byte aligned. If convert is true, a 0 will be added in front of the string in case it needs to be aligned. Defaults to false.
const schema = Joi.string().hex();

Possible validation errors: string.hex, string.hexAlign

string.hostname()

Requires the string value to be a valid hostname as per RFC1123.

const schema = Joi.string().hostname();

Possible validation errors: string.hostname

string.insensitive()

Allows the value to match any value in the allowed list or disallowed list in a case insensitive comparison.

const schema = Joi.string().valid('a').insensitive();

string.ip([options])

Requires the string value to be a valid ip address.

  • options - optional settings:
    • version - One or more IP address versions to validate against. Valid values: ipv4, ipv6, ipvfuture
    • cidr - Used to determine if a CIDR is allowed or not. Valid values: optional, required, forbidden
// Accept only ipv4 and ipv6 addresses with a CIDR
const schema = Joi.string().ip({
  version: [
    'ipv4',
    'ipv6'
  ],
  cidr: 'required'
});

Possible validation errors: string.ip, string.ipVersion

string.isoDate()

Requires the string value to be in valid ISO 8601 date format.

If the validation convert option is on (enabled by default), the string will be forced to simplified extended ISO format (ISO 8601). Be aware that this operation uses javascript Date object, which does not support the full ISO format, so a few formats might not pass when using convert.

const schema = Joi.string().isoDate();
schema.validate('2018-11-28T18:25:32+00:00'); // No Error
schema.validate('20181-11-28T18:25:32+00:00'); // ValidationError: must be a valid 8601 date
schema.validate(''); // ValidationError: must be a valid 8601 date

Possible validation errors: string.isoDate

string.isoDuration()

Requires the string value to be in valid ISO 8601 duration format.

const schema = Joi.string().isoDuration();
schema.validate('P3Y6M4DT12H30M5S'); // No Error
schema.validate('2018-11-28T18:25:32+00:00'); // ValidationError: must be a valid ISO 8601 duration
schema.validate(''); // ValidationError: must be a valid ISO 8601 duration

Possible validation errors: string.isoDuration

string.length(limit, [encoding])

Specifies the exact string length required where:

  • limit - the required string length or a reference.
  • encoding - if specified, the string length is calculated in bytes using the provided encoding.
const schema = Joi.string().length(5);
const schema = Joi.object({
  length: Joi.string().required(),
  value: Joi.string().length(Joi.ref('length'), 'utf8').required()
});

Possible validation errors: string.length, string.ref

string.lowercase()

Requires the string value to be all lowercase. If the validation convert option is on (enabled by default), the string will be forced to lowercase.

const schema = Joi.string().lowercase();

Possible validation errors: string.lowercase

string.max(limit, [encoding])

Specifies the maximum number of string characters where:

  • limit - the maximum number of string characters allowed or a reference.
  • encoding - if specified, the string length is calculated in bytes using the provided encoding.
const schema = Joi.string().max(10);
const schema = Joi.object({
  max: Joi.string().required(),
  value: Joi.string().max(Joi.ref('max'), 'utf8').required()
});

Possible validation errors: string.max, string.ref

string.min(limit, [encoding])

Specifies the minimum number string characters where:

  • limit - the minimum number of string characters required or a reference.
  • encoding - if specified, the string length is calculated in bytes using the provided encoding.
const schema = Joi.string().min(2);
const schema = Joi.object({
  min: Joi.string().required(),
  value: Joi.string().min(Joi.ref('min'), 'utf8').required()
});

Possible validation errors: string.min, string.ref

string.normalize([form])

Requires the string value to be in a Unicode normalized form. If the validation convert option is on (enabled by default), the string will be normalized.

  • form - The Unicode normalization form to use. Valid values: NFC [default], NFD, NFKC, NFKD
const schema = Joi.string().normalize(); // defaults to NFC
const schema = Joi.string().normalize('NFC'); // canonical composition
const schema = Joi.string().normalize('NFD'); // canonical decomposition
const schema = Joi.string().normalize('NFKC'); // compatibility composition
const schema = Joi.string().normalize('NFKD'); // compatibility decomposition

Possible validation errors: string.normalize

string.pattern(regex, [name | options]) - aliases: regex

Defines a pattern rule where:

  • regex - a regular expression object the string value must match against. Note that if the pattern is a regular expression, for it to match the entire key name, it must begin with ^ and end with $.
  • name - optional name for patterns (useful with multiple patterns).
  • options - an optional configuration object with the following supported properties:
    • name - optional pattern name.
    • invert - optional boolean flag. Defaults to false behavior. If specified as true, the provided pattern will be disallowed instead of required.
const schema = Joi.string().pattern(/^[abc]+$/);

const inlineNamedSchema = Joi.string().pattern(/^[0-9]+$/, 'numbers');
inlineNamedSchema.validate('alpha'); // ValidationError: "value" with value "alpha" fails to match the numbers pattern

const namedSchema = Joi.string().pattern(/^[0-9]+$/, { name: 'numbers'});
namedSchema.validate('alpha'); // ValidationError: "value" with value "alpha" fails to match the numbers pattern

const invertedSchema = Joi.string().pattern(/^[a-z]+$/, { invert: true });
invertedSchema.validate('lowercase'); // ValidationError: "value" with value "lowercase" matches the inverted pattern: [a-z]

const invertedNamedSchema = Joi.string().pattern(/^[a-z]+$/, { name: 'alpha', invert: true });
invertedNamedSchema.validate('lowercase'); // ValidationError: "value" with value "lowercase" matches the inverted alpha pattern

Possible validation errors: string.pattern.base, string.pattern.invert.base, string.pattern.invert.name, string.pattern.name

string.replace(pattern, replacement)

Replace characters matching the given pattern with the specified replacement string where:

  • pattern - a regular expression object to match against, or a string of which all occurrences will be replaced.
  • replacement - the string that will replace the pattern.
const schema = Joi.string().replace(/b/gi, 'x');
await schema.validateAsync('abBc');  // return value will be 'axxc'

When pattern is a string all its occurrences will be replaced.

string.token()

Requires the string value to only contain a-z, A-Z, 0-9, and underscore _.

const schema = Joi.string().token();

Possible validation errors: string.token

string.trim([enabled])

Requires the string value to contain no whitespace before or after. If the validation convert option is on (enabled by default), the string will be trimmed.

Parameters are:

  • enabled - optional parameter defaulting to true which allows you to reset the behavior of trim by providing a falsy value.
const schema = Joi.string().trim();
const schema = Joi.string().trim(false); // disable trim flag

Possible validation errors: string.trim

string.truncate([enabled])

Specifies whether the string.max() limit should be used as a truncation.

Parameters are:

  • enabled - optional parameter defaulting to true which allows you to reset the behavior of truncate by providing a falsy value.
const schema = Joi.string().max(5).truncate();

string.uppercase()

Requires the string value to be all uppercase. If the validation convert option is on (enabled by default), the string will be forced to uppercase.

const schema = Joi.string().uppercase();

Possible validation errors: string.uppercase

string.uri([options])

Requires the string value to be a valid RFC 3986 URI.

  • options - optional settings:
    • scheme - Specifies one or more acceptable Schemes, should only include the scheme name. Can be an Array or String (strings are automatically escaped for use in a Regular Expression).
    • allowRelative - Allow relative URIs. Defaults to false.
    • relativeOnly - Restrict only relative URIs. Defaults to false.
    • allowQuerySquareBrackets - Allows unencoded square brackets inside the query string. This is NOT RFC 3986 compliant but query strings like abc[]=123&abc[]=456 are very common these days. Defaults to false.
    • domain - Validate the domain component using the options specified in string.domain().
// Accept git or git http/https
const schema = Joi.string().uri({
  scheme: [
    'git',
    /git\+https?/
  ]
});

Possible validation errors: string.uri, string.uriCustomScheme, string.uriRelativeOnly, string.domain

symbol

Generates a schema object that matches a Symbol data type.

If the validation convert option is on (enabled by default), the mappings declared in map() will be tried for an eventual match.

Supports the same methods of the any() type.

const schema = Joi.symbol().map({ 'foo': Symbol('foo'), 'bar': Symbol('bar') });
await schema.validateAsync('foo');

Possible validation errors: symbol.base

symbol.map(map)

Allows values to be transformed into Symbols, where:

  • map - mapping declaration that can be:
    • an object, where keys are strings, and values are Symbols
    • an array of arrays of length 2, where for each sub-array, the 1st element must be anything but an object, a function or a Symbol, and the 2nd element must be a Symbol
    • a Map, following the same principles as the array above
const schema = Joi.symbol().map([
    [1, Symbol('one')],
    ['two', Symbol('two')]
]);

Possible validation errors: symbol.map

Extensions

The extend() method adds custom types to joi. Extensions can be :

  • a single extension object
  • a factory function generating an extension object

Full documentation is upcoming.

const Joi = require('@hapi/joi');

const custom = Joi.extend((joi) => {

    return {
        type: 'million',
        base: joi.number(),
        messages: {
            'million.base': '"{{#label}}" must be at least a million',
            'million.big': '"{{#label}}" must be at least five millions',
            'million.round': '"{{#label}}" must be a round number',
            'million.dividable': '"{{#label}}" must be dividable by {{#q}}'
        },
        coerce(value, helpers) {

            // Only called when prefs.convert is true

            if (helpers.schema.$_getRule('round')) {
                return { value: Math.round(value) };
            }
        },
        validate(value, helpers) {

            // Base validation regardless of the rules applied

            if (value < 1000000) {
                return { value, errors: helpers.error('million.base') };
            }

            // Check flags for global state

            if (schema.$_getFlag('big') &&
                value < 5000000) {

                return { value, errors: helpers.error('million.big') };
            }
        },
        rules: {
            big: {
                alias: 'large',
                method() {

                    return this.$_setFlag('big', true);
                }
            },
            round: {
                convert: true,              // Dual rule: converts or validates
                method() {

                    return this.$_addRule('round');
                },
                validate(value, helpers, args, options) {

                    // Only called when prefs.convert is false (due to rule convert option)

                    if (value % 1 !== 0) {
                        return helpers.error('million.round');
                    }
                }
            },
            dividable: {
                multi: true,                // Rule supports multiple invocations
                method(q) {

                    return this.$_addRule({ name: 'dividable', args: { q } });
                },
                args: [
                    {
                        name: 'q',
                        ref: true,
                        assert: (value) => typeof value === 'number' && !isNaN(value),
                        message: 'must be a number'
                    }
                ],
                validate(value, helpers, args, options) {

                    if (value % args.q === 0) {
                        return value;       // Value is valid
                    }

                    return helpers.error('million.dividable', { q: args.q });
                }
            },
            even: {
                method() {

                    // Rule with only method used to alias another rule

                    return this.dividable(2);
                }
            }
        }
    };
});

const schema = custom.object({
    a: custom.million().round().dividable(Joi.ref('b')),
    b: custom.number(),
    c: custom.million().even().dividable(7),
    d: custom.million().round().prefs({ convert: false }),
    e: custom.million().large()
});

Advanced functions

$_root

TODO

$_super

TODO

$_temp

TODO

$_terms

TODO

$_addRule(options)

TODO

$_compile(schema, options)

TODO

$_createError(code, value, local, state, prefs, options)

TODO

$_getFlag(name)

TODO

$_getRule(name)

TODO

$_mapLabels(path)

TODO

$_match(value, state, prefs, overrides)

TODO

$_modify(options)

TODO

$_mutateRebuild()

TODO

$_mutateRegister(schema, options)

TODO

$_property(name)

TODO

$_reach(path)

TODO

$_rootReferences()

TODO

$_setFlag(name, value, options)

TODO

$_validate(value, state, prefs)

TODO

Errors

ValidationError

joi throws or returns ValidationError objects containing :

  • name - 'ValidationError'.
  • isJoi - true.
  • details - an array of errors :
    • message - string with a description of the error.
    • path - ordered array where each element is the accessor to the value where the error happened.
    • type - type of the error.
    • context - object providing context of the error containing:
      • key - key of the value that erred, equivalent to the last element of details.path.
      • label - label of the value that erred, or the key if any, or the default messages.root.
      • value - the value that failed validation.
      • other error specific properties as described for each error code.
  • annotate() - function that returns a string with an annotated version of the object pointing at the places where errors occurred. Takes an optional parameter that, if truthy, will strip the colors out of the output.

List of errors

alternatives.all

The value did not match all of the alternative schemas.

alternatives.any

No alternative was found to test against the input due to try criteria.

alternatives.match

No alternative matched the input due to specific matching rules for at least one of the alternatives.

Additional local context properties:

{
    details: Array<object>, // An array of details for each error found while trying to match to each of the alternatives
    message: string // The combined error messages
}

alternatives.one

The value matched more than one alternative schema.

alternatives.types

The provided input did not match any of the allowed types.

Additional local context properties:

{
    types: Array<string> // The list of expected types
}

any.custom

A custom validation method threw an exception.

Additional local context properties:

{
    error: Error // The error thrown
}

any.default

If your any.default() generator function throws error, you will have it here.

Additional local context properties:

{
    error: Error // Error generated during the default value function call
}

any.failover

If your any.failover() generator function throws error, you will have it here.

Additional local context properties:

{
    error: Error // Error generated during the failover value function call
}

any.invalid

The value matched a value listed in the invalid values.

Additional local context properties:

{
    invalids: Array<any> // Contains the list of the invalid values that should be rejected
}

any.only

Only some values were allowed, the input didn't match any of them.

Additional local context properties:

{
    valids: Array<any> // Contains the list of the valid values that were expected
}

any.ref

A reference was used in rule argument and the value pointed to by that reference in the input is not valid.

Additional local context properties:

{
    arg: string, // The argument name
    reason: string, // The reason the referenced value is invalid
    ref: Reference // Reference used
}

any.required

A required value wasn't present.

any.unknown

A value was present while it wasn't expected.

array.base

The value is not of Array type or could not be cast to an Array from a string.

array.excludes

The array contains a value that is part of the exclusion list.

Additional local context properties:

{
    pos: number // Index where the value was found in the array
}

array.includesRequiredBoth

Some values were expected to be present in the array and are missing. This error happens when we have a mix of labeled and unlabeled schemas.

Additional local context properties:

{
    knownMisses: Array<string>, // Labels of all the missing values
    unknownMisees: number // Count of missing values that didn't have a label
}

array.includesRequiredKnowns

Some values were expected to be present in the array and are missing. This error happens when we only have labeled schemas.

Additional local context properties:

{
    knownMisses: Array<string> // Labels of all the missing values
}

array.includesRequiredUnknowns

Some values were expected to be present in the array and are missing. This error happens when we only have unlabeled schemas.

Additional local context properties:

{
    unknownMisees: number // Count of missing values that didn't have a label
}

array.includes

The value didn't match any of the allowed types for that array.

Additional local context properties:

{
    pos: number // Index where the value was found in the array
}

array.length

The array is not of the expected length.

Additional local context properties:

{
    limit: number // Length that was expected for this array
}

array.max

The array has more elements than the maximum allowed.

Additional local context properties:

{
    limit: number // Maximum length that was expected for this array
}

array.min

The array has less elements than the minimum allowed.

Additional local context properties:

{
    limit: number // Minimum length that was expected for this array
}

array.orderedLength

Given an array.ordered(), that array has more elements than it should.

Additional local context properties:

{
    pos: number, // Index where the value was found in the array
    limit: number // Maximum length that was expected for this array
}

array.sort

The array did not match the required sort order.

Additional local context properties:

{
    order: string, // 'ascending' or 'descending'
    by: string // The object key used for comparison
}

array.sort.mismatching

Failed sorting the array due to mismatching item types.

array.sort.unsupported

Failed sorting the array due to unsupported item types.

Additional local context properties:

{
    type: string // The unsupported array item type
}

array.sparse

An undefined value was found in an array that shouldn't be sparse.

Additional local context properties:

{
    pos: number // Index where an undefined value was found in the array
}

array.unique

A duplicate value was found in an array.

Additional local context properties:

{
    pos: number, // Index where the duplicate value was found in the array
    dupePos: number, // Index where the first appearance of the duplicate value was found in the array
    dupeValue: any // Value with which the duplicate was met
}

array.hasKnown

The schema on an array.has() was not found in the array. This error happens when the schema is labeled.

Additional local context properties:

{
    patternLabel: string // Label of assertion schema
}

array.hasUnknown

The schema on an array.has() was not found in the array. This error happens when the schema is unlabeled.

binary.base

The value is either not a Buffer or could not be cast to a Buffer from a string.

binary.length

The buffer was not of the specified length.

Additional local context properties:

{
    limit: number // Length that was expected for this buffer
}

binary.max

The buffer contains more bytes than expected.

Additional local context properties:

{
    limit: number // Maximum length that was expected for this buffer
}

binary.min

The buffer contains less bytes than expected.

Additional local context properties:

{
    limit: number // Minimum length that was expected for this buffer
}

boolean.base

The value is either not a boolean or could not be cast to a boolean from one of the truthy or falsy values.

date.base

The value is either not a date or could not be cast to a date from a string or a number.

date.format

The date does not match the required format.

Additional local context properties:

{
    format: string // The required format
}

date.greater

The date is over the limit that you set.

Additional local context properties:

{
    limit: Date // Maximum date
}

date.less

The date is under the limit that you set.

Additional local context properties:

{
    limit: Date // Minimum date
}

date.max

The date is over or equal to the limit that you set.

Additional local context properties:

{
    limit: Date // Maximum date
}

date.min

The date is under or equal to the limit that you set.

Additional local context properties:

{
    limit: Date // Minimum date
}

date.strict

Occurs when the input is not a Date type and convert is disabled.

function.arity

The number of arguments for the function doesn't match the required number.

Additional local context properties:

{
    n: number // Expected arity
}

function.class

The input is not a JavaScript class.

function.maxArity

The number of arguments for the function is over the required number.

Additional local context properties:

{
    n: number // Maximum expected arity
}

function.minArity

The number of arguments for the function is under the required number.

Additional local context properties:

{
    n: number // Minimum expected arity
}

number.base

The value is not a number or could not be cast to a number.

number.greater

The number is lower or equal to the limit that you set.

Additional local context properties:

{
    limit: number // Minimum value that was expected for this number
}

number.infinity

The number is Infinity or -Infinity.

number.integer

The number is not a valid integer.

number.less

The number is higher or equal to the limit that you set.

Additional local context properties:

{
    limit: number // Maximum value that was expected for this number
}

number.max

The number is higher than the limit that you set.

Additional local context properties:

{
    limit: number // Maximum value that was expected for this number
}

number.min

The number is lower than the limit that you set.

Additional local context properties:

{
    limit: number // Minimum value that was expected for this number
}

number.multiple

The number could not be divided by the multiple you provided.

Additional local context properties:

{
    multiple: number // The number of which the input is supposed to be a multiple of
}

number.negative

The number was positive.

number.port

The number didn't look like a port number.

number.positive

The number was negative.

number.precision

The number didn't have the required precision.

Additional local context properties:

{
    limit: number // The precision that it should have had
}

number.unsafe

The number is not within the safe range of JavaScript numbers.

object.unknown

An unexpected property was found in the object.

Additional local context properties:

{
    child: string // Property that is unexpected
}

object.and

The AND condition between the properties you specified was not satisfied in that object.

Additional local context properties:

{
    present: Array<string>, // List of properties that are set
    presentWithLabels: Array<string>, // List of labels for the properties that are set
    missing: Array<string>, // List of properties that are not set
    missingWithLabels: Array<string> // List of labels for the properties that are not set
}

object.assert

The schema on an object.assert() failed to validate.

Additional local context properties:

{
    subject: object, // The assertion subject. When it is a reference, use subject.key for the display path.
    message: string // Custom message when provided
}

object.base

The value is not of the expected type.

Additional local context properties:

{
    type: string // The expected type
}

object.length

The number of keys for this object is not of the expected length.

Additional local context properties:

{
    limit: number // Number of keys that was expected for this object
}

object.max

The number of keys for this object is over or equal to the limit that you set.

Additional local context properties:

{
    limit: number // Maximum number of keys
}

object.min

The number of keys for this object is under or equal to the limit that you set.

Additional local context properties:

{
    limit: number // Minimum number of keys
}

object.missing

The OR or XOR condition between the properties you specified was not satisfied in that object, none of it were set.

Additional local context properties:

{
    peers: Array<string>, // List of properties were none of it was set
    peersWithLabels: Array<string> // List of labels for the properties were none of it was set
}

object.nand

The NAND condition between the properties you specified was not satisfied in that object.

Additional local context properties:

{
    main: string, // One of the properties that was present
    mainWithLabel: string, // The label of the `main` property
    peers: Array<string>, // List of the other properties that were present
    peersWithLabels: Array<string> // List of the labels of the other properties that were present
}

object.pattern.match

The object keys failed to match a pattern's matches requirement.

Additional local context properties:

{
    details: Array<object>, // An array of details for each error found while trying to match to each of the alternatives
    message: string, // The combined error messages
    matches: Array<string>  // The matching keys
}

object.refType

The object is not a Joi.ref().

object.rename.multiple

Another rename was already done to the same target property.

Additional local context properties:

{
    from: string, // Origin property name of the rename
    to: string, // Target property of the rename
    pattern: boolean // Indicates if the rename source was a pattern (regular expression)
}

object.rename.override

The target property already exists and you disallowed overrides.

Additional local context properties:

{
    from: string, // Origin property name of the rename
    to: string, // Target property of the rename
    pattern: boolean // Indicates if the rename source was a pattern (regular expression)
}

object.schema

The object was not a joi schema.

Additional local context properties:

{
    type: string // The required schema
}

object.instance

The object is not of the type you specified.

Additional local context properties:

{
    type: string // Type name the object should have been
}

object.with

Property that should have been present at the same time as another one was missing.

Additional local context properties:

{
    main: string, // Property that triggered the check
    mainWithLabel: string, // Label of the property that triggered the check
    peer: string, // Property that was missing
    peerWithLabels: string // Label of the other property that was missing
}

object.without

Property that should have been absent at the same time as another one was present.

Additional local context properties:

{
    main: string, // Property that triggered the check
    mainWithLabel: string, // Label of the property that triggered the check
    peer: string, // Property that was present
    peerWithLabels: string // Label of the other property that was present
}

object.xor

The XOR condition between the properties you specified was not satisfied in that object.

Additional local context properties:

{
    peers: Array<string>, // List of properties where none of it or too many of it was set
    peersWithLabels: Array<string> // List of labels for the properties where none of it or too many of it was set
}

object.oxor

The optional XOR condition between the properties you specified was not satisfied in that object.

Additional local context properties:

{
    peers: Array<string>, // List of properties where too many of it was set
    peersWithLabels: Array<string> // List of labels for the properties where too many of it was set
}

string.alphanum

The string doesn't only contain alphanumeric characters.

string.base64

The string isn't a valid base64 string.

string.base

The input is not a string.

string.creditCard

The string is not a valid credit card number.

string.dataUri

The string is not a valid data URI.

string.domain

The string is not a valid domain name.

string.email

The string is not a valid e-mail.

Additional local context properties:

{
    invalids: [string] // Array of invalid emails
}

string.empty

When an empty string is found and denied by invalid values.

string.guid

The string is not a valid GUID.

string.hexAlign

The string contains hexadecimal characters but they are not byte-aligned.

string.hex

The string is not a valid hexadecimal string.

string.hostname

The string is not a valid hostname.

string.ipVersion

The string is not a valid IP address considering the provided constraints.

Additional local context properties:

{
    cidr: string, // CIDR used for the validation
    version: Array<string> // List of IP version accepted
}

string.ip

The string is not a valid IP address.

Additional local context properties:

{
    cidr: string // CIDR used for the validation
}

string.isoDate

The string is not a valid ISO date string.

string.isoDuration

The string must be a valid ISO 8601 duration.

string.length

The string is not of the expected length.

Additional local context properties:

{
    limit: number, // Length that was expected for this string
    encoding: undefined | string // Encoding specified for the check if any
}

string.lowercase

The string isn't all lower-cased.

string.max

The string is larger than expected.

Additional local context properties:

{
    limit: number, // Maximum length that was expected for this string
    encoding: undefined | string // Encoding specified for the check if any
}

string.min

The string is smaller than expected.

Additional local context properties:

{
    limit: number, // Minimum length that was expected for this string
    encoding: undefined | string // Encoding specified for the check if any
}

string.normalize

The string isn't valid in regards of the normalization form expected.

Additional local context properties:

{
    form: string // Normalization form that is expected
}

string.pattern.base

The string didn't match the regular expression.

Additional local context properties:

{
    name: undefined, // Undefined since the regular expression has no name
    pattern: string // Regular expression
}

string.pattern.name

The string didn't match the named regular expression.

Additional local context properties:

{
    name: string, // Name of the regular expression
    pattern: string // Regular expression
}

string.pattern.invert.base

The string matched the regular expression while it shouldn't.

Additional local context properties:

{
    name: undefined, // Undefined since the regular expression has no name
    pattern: string // Regular expression
}

string.pattern.invert.name

The string matched the named regular expression while it shouldn't.

Additional local context properties:

{
    name: string, // Name of the regular expression
    pattern: string // Regular expression
}

string.token

The string isn't a token.

string.trim

The string contains whitespace around it.

string.uppercase

The string isn't all upper-cased.

string.uri

The string isn't a valid URI.

string.uriCustomScheme

The string isn't a valid URI considering the custom schemes.

Additional local context properties:

{
    scheme: string // Scheme prefix that is expected in the URI
}

string.uriRelativeOnly

The string is a valid relative URI.

symbol.base

The input is not a Symbol.

symbol.map

The input is not a Symbol or could not be converted to one.

Changelog

#2226
object.with and object.without throw error on $ prefixed keys
#2218
Maximum call stack size exceeded​​ error for dataUri validation
#2212
Joi.string().email() considers "a@a.com/asd" as valid email
#2208
fix: describe() on schema with default value null
#2207
describe() on schema with default value null results in "Cannot read property 'Symbol(literal)' of null"
#2205
Cannot require a minimal number of matching object properties with `pattern`
#2190
Joi.string().domain() treats an email address as a valid domain name
#2187
Giving an array argument to any.allow(...values) gives incorrect error
#2181
Joi.alternatives produces confusing message when used with nested object and `{ abortEarly: false }`
#2176
joi.types() is missing `func` alias
#2173
[Request] Allow mixing patch version
#2168
Date fails to enforce format when value is a number string
#2167
Error.captureStackTrace can't be used in all browser builds
#2165
Cannot read property 'delete' of undefined
#2156
node.get is not a function when validating
#2147
Joi v16: TypeError issue with valid(Joi.ref(x)).error()
#2134
Joi.any().default(<object>).describe() throws validation errors
#2131
TypeError: false.byteLength is not a function
#2128
when() fails when combined with prefs()
#2119
Use ^version
#2118
array.items() fails to invalidate when custom item error is used
#2116
Support `.when({ is, then })` without subject ref
#2113
Valid emails are considered invalid
#2111
Joi.only is not a function
#2103
Support errors in manifest
#2102
Always convert -0 to 0
#2101
Apply link.concat() on resolved schema
#2099
Add when() break
#2097
Number validation fails with "1E3"
#2096
Apply link whens on linked schema, not the link
#2093
Manifest type conflicts with key type
#2092
Support Joi.in() for object keys
#2091
"-0" throw number.unsafe
#2089
Joi.in()
#2088
Always perform deep equal on valid() and invalid()
#2087
Fix comparison of array values (literals and references)
#2086
Preference to change label to path edge instead of full path
#2085
Default assert() to include stack
#2084
Shared schemas in links
#2083
Add a browser build to the github repo and npm package
#2082
Fix error thrown in the browser build. Closes #2081
#2081
The browser build (produced by webpack) throws an error when loading
#2080
Named schema links
#2079
Support `no` in when()
#2078
Default `is` to Joi.invalid(null, false, 0, '').required()
#2077
Compile valid values into valid+override
#2076
Allow/disallow list override
#2075
Log when() partials
#2074
Compile function into Joi.custom()
#2073
When object.pattern() matches option is not an array(), apply to each item
#2072
Custom function error shortcut
#2068
schema.describe() does not work, when default value is assigned to array in schema
#2065
Change alternatives to be consistent with other spread arguments
#2064
Throw on invalid schema during validation
#2062
Support chained when()
#2061
Keep switch as single condition on when() and conditional()
#2060
object.assert() ref should be relative to parent, not self
#2059
Support multiple usage of same schema with id
#2056
Schema test coverage
#2054
Rename alternatives.when() to alternatives.conditional()
#2051
Support for combine schema: allOf, oneOf, anyOf
#2049
Compile literals into any type with exact literal
#2048
Replace marker with Symbol.for()
#2046
Cast multi values of into a single type with valid()
#2041
Exclude error stack trace by default
#2040
Replace boolean.insensitive() with sensitive() and not apply to allow()
#2039
Allow mapping flags to rule methods with a different name
#2038
Stop matching object patterns once a match is found
#2037
v16.0.0 Release Notes
#2036
{ result, error } changed to error undefined instead of null
#2035
Skip error rendering preference
#2034
Consolidate date format errors
#2033
msg() template function to access other messages
#2032
Support custom sync functions for rules
#2031
Remove object and array string coerce
#2030
string.isoDate() fails on allow() and convert:false
#2027
Support templates as object.assert() subject
#2026
Change object.assert error context and rule argument name
#2024
Remove binary and string encoding support from the browser
#2023
Rule arguments validation
#2022
Support reverse order coerce
#2019
Consolidate refs with args
#2018
Support joi schema in refs assert
#2016
Consolidate refs assert's message/code
#2015
Ensure all levels of coerce are only called on non-undefined values
#2014
Change all _methods used on schema to use definition
#2013
Expose all internal extend() options externally
#2012
Rename func to function
#2010
New extension API
#2009
Global defaults
#2007
Change Infinity errors from any.invalid to number.infinity
#2006
Change error code any.empty to string.empty
#2005
Merging of two empty() should allow '' if it was explicitly defined
#2002
Remove prefs schema validation
#2001
Remove joi.defaults()
#1999
Fix outdated use of Joi.func().ref()
#1998
Split validate() to sync and async versions
#1995
Replace strip flag with result flag
#1994
Joi.string().uri() accepts 'http:/' as valid URL
#1993
Root reference
#1987
Extension build() support
#1986
Improve schema description validation
#1985
Refactor root
#1983
Change any.notes() to any.note() and require separate arguments
#1982
Change any.tags() to any.tag() and require separate arguments
#1981
Change any.example() to append by default
#1980
Rename string.regex() to string.pattern()
#1979
Link to root (regardless of depth)
#1978
Change only() to flag instead of alias of valid()
#1977
Replace date multiple and timestamp flag with format
#1976
Rename object.allowUnknown error to object.unknown
#1975
Remove description for `default()` function
#1974
Deep clone all values returned in describe()
#1973
Behavior of .concat() with tests redefinition
#1972
Applying `raw` after successful validation
#1968
Repalce lazy with link
#1965
How to properly detect domains?
#1962
Don't require pre function to take 3 arguments
#1961
Lazy once ignored when using with when()
#1960
Fix object peer dependencies error path
#1959
Debug tools
#1958
Warnings
#1957
Feature: Marking options as deprecated
#1956
Extension messages override base
#2047
Replace marker with Symbol.for()
#1926
Add legacy API
#1808
bool() cannot be binded
#1801
remove strip from defaults now that it has been removed
15.0.1
breaking changes
#1761
Validate object keys related to another value
#1753
Override extension language
#1750
Pass options to pattern validation to support refs
#1748
.pattern doesn't respect .valid when using .ref
#1747
Extension which has a return value in setup() does not call validate()
#1714
Undocumented strip option on Joi.validate
#1704
Resolved issue of maximum call stack exceeded
#1700
base64 validation returns RangeError
#1776
Replace isemail with @hapi/address
#1768
Fix dependency
#1928
Add legacy API
#1766
Change module namespace
#1691
joi.bind yields any() methods not fully bound
#1665
path-related methods (`with(), `nand()`...) broken when applied on `func()`
#1631
Destructuring Throws Fatal
#1659
Add array().assertItem(). Closes #1656
#1656
Complex array validation requirements
#1608
Custom message overload another one
#1528
joi errors not overriding for nested objects
#1219
In case custom error messages are passed to Joi.any.error, joi.validate returning parent object error even if child validation fails.
#1658
Extensions remove language of previous extension with the same base
#1654
Bump to lab@18. Fixes #1653.
#1647
Add object().oxor(). Closes #1628
#1628
xor but none required
#1607
invalid mime types on data uri
#1638
fix condition, add tests for safe numbers
#1637
Using Number.MAX_SAFE_INTEGER throw error that number unsafe.
#1634
Remove engines
#1622
Maximum call stack size exceeded​​ error from Joi.defaults with Joi.empty flags
#1617
object().with using nested paths validates when it shouldn't in Joi 14
#1615
14.0.0 Release Notes
#1614
Default stripUnknown = true to only strip object keys, not arrays
#1595
Overriding array.min() when using reach
#1568
Trying to get multiple custom error messages in details array with {abortEarly: false}
#1555
Chaining multiple examples does not overwrite the old examples
#1554
#1477 Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor()
#1544
Error at integer validation
#1504
Max safe integers
#1478
.example SHOULD perform validation on the provided value
#1477
Joi.object().or() does not support nested paths
#1429
Joi.string().regex() with support for all modifiers
#1364
Need to override twice the key name for error messages
#1258
Feature Request: lazy once
#1247
Year-only iso date string is parsed incorrectly
#1191
Chaining string.insensitive() will not convert values with lowercase/uppercase modifiers
#1127
Make certain rules override themselves
#1113
Number validation on '0x1' reports no error with a value of 0.
#1562
Add symbol() type
#1420
Add Symbol() support
#1558
Add value to number.base errors
#1532
Add enabled flag to string.trim()
#1525
Add boolean flag to Joi.string().trim()
#1511
Add optional "config" param to array.unique for ignoreUndefined. Closes #1498
#1510
Data uri validation
#1498
Validating unique optional fields in array elements.
#1487
Allow square braces in URL validation
#1461
URI validator rejects query param square brackets
#999
Where is the documentation for `this.createError()`?
#1521
Extended object does not parse JSON
#1515
Joi.reach() can no longer handles empty string path
#1514
remove indirect require reference to index.js
#1513
require('../') statement in schemas.js causing bundler issues.
#1500
add date greater less rules
#1499
Allow object keys to be verified by schema
#1382
Add a key validator with Joi objects
#1000
Correct way to write an "identity" extension?
#1479
Is it possible to capture the value of field being validated in custom error messages using the options - language
#1438
Use Set() for handling of unprocessed keys
#1422
Add byteAligned option to hex string
#1415
Use Set() for internal Set backend
#1476
Cannot validate an array with 'constructor' as unique entry
#1452
Add new validation number().port()
#1448
Include describe() documentation in API. Fixes #1447
#1435
Add an object.append() method. Fixes #1381.
#1433
Changed a separator for path parameter to pre-split array approach for Joi.reach
#1423
Avoid redundant copies of settings
#1414
Fix cloned valid() / invalid() object values
#1383
Add an separator parameter to Joi.reach
#1381
Add an object.append() method
#1346
Validate port numbers
#1392
undefined in the array with label returns wrong missing value message
#1395
Asserts that two arguments are provided to object.with() and object.without()
#1386
Fix object pattern in combination with empty
#1354
Remove validation from .example
#1350
joi.ref doesn't work properly with max() function for dependant dates
#1189
Should .example perform validation on the provided value?
#1334
Impossible to disable language.key in options
#1328
13.0.0 Release Notes
#1327
Bump joi to node 8+
12.1.0
breaking changes
#1757
Commercial version of v12 branch
#1326
12.0.0 Release Notes
#921
$-sign in object keys are escaped in the ValidationError message
#1325
Allow `alternatives.when` to "peek" inside the current value
#1230
Missing `language` entry in `joi.extend` causes obscure runtime error
#1311
import { any } does not work on v11
#1240
Fixes [#1239]
#1239
Rename multiple keys to another name
#1308
Add Joi.func().class()
#1316
Remove items module dependency
#1315
Add promise-like API to validate. Fixes #1314.
#1314
Support promises on `validate()`
#1291
Add string.normalize for unicode normalization
#1289
Feature request: Unicode normalization
#1266
remove empty flag if only reset is used
#1249
describe doesn't work for empty() breaking lout
#1303
empty string is wrongly accepted as a timestamp
#1302
11.0.0 Release Notes
#1283
Error: Item cannot come after itself
#1282
There is a bug in 10.6.0 API Reference.
#1278
Joi.defaults(): Cannot default object type
#1256
Add `Joi.defaults()`
#1254
ipv6 with cidr greater than 32
#1235
Fix Value Range for IPv6 CIDRs
#1232
ipv6 string with mask between 33 and 128 are rejected.
#1229
Update isemail from 2.x.x to 3.x.x
#1197
Allow passing an option to string().isoDate()
#1196
string isoDate should allow the string to be converted to same format as date iso schema
#1167
Errors: context.key is actually the label, not the key
#1126
Passes the "default" function to the schema description
#1121
[Request] Add detail to .describe for function defaults
#931
Email validation doesn't allow emails which are compliant with RFC 6530
#1215
#1201 - setup can return joi object to replace origin schema
#1211
Performance Improvements for string().guid()
#1206
Added the ability to use a reference for Array min/max/length
#1201
Question: how to extend joi to add some key by rule?
#1174
Fix #1156 - Adds support for optional base64 padding validation.
#1156
base64 validation too strict; padding is optional
#1017
Array length cannot reference to another field
#1199
Make isemail an optional dependency
#1203
Nested child/uncle condition causes annotate() to throw
#1183
add forbiddenKeys method to object
#1161
Alternatives respect subsequent "when"s if first has only "otherwise"
#1151
Alternatives based on a type with only otherwise take precedence over any following one
#1146
Keep converted values even when stripped for reference uses
#1132
Add "options" to describe output
#1130
Joi.any().options() should be reported in .describe()
#1119
alternatives doesn't work with error
#844
Label in object.and()
#1131
Add basic error overriding
#1143
number().integer() can fail for values outside MAX_SAFE_INTEGER
#1145
Don't try to touch custom error messages with attempt message
#1144
Possible bug in custom Error message
#1097
Fix #964 Joi wrong value parsing
#964
Joi wrong value parsing
#1128
Avoid unnecessary clones
#1067
"Describe" behavior changes for "implicit" Any with extended Joi
#1047
Creating multiple extensions for the same base type
#983
Unexpected interaction between Joi.object().unknown() and stripUnknown
#831
Joi valid fails, when ref is used with a stripped key.
#1103
allow param defaults to be set by the param validations
#1095
noDefaults behaviour with any.empty()
#1076
Added support for ISO_8601 expansion (+/-YYYYYY)
#1075
Allow shorthand accessor string in array().unique()
#1073
Provide value which duplicates an item in array().unique()
#1072
Path of array().unique() is wrong
10.0.6
breaking changes
#1065
Fix boolean strings parsing
#1054
adding validation for unnecessary arguments in primary types.
#1009
Request: Warn when functions are passed unexpected arguments
#1052
[Request] truthy/falsy case insensitive
#1039
trim + empty confuses me
#1037
10.0.0 Release Notes
#1035
Implement String.regex "invalidate" configuration
#1034
added support for string.uri relativeOnly option
#1032
Clean up any.valid code
#1030
Conditional validation of object properties with different parent key
#1028
Extend describe() for type
#1027
Extending describe() to include renames in metadata
#1026
object renames do not appear in describe api.
#1020
Joi.string().invalid (not, disallow) doesn't support regex?
#1016
Added a string.base64() method.
#1015
Suggestion: Joi.string().uri({ allowRelativeOnly })
#1010
Update Joi.validate options with removal of error
#998
Add support for truthy/falsy boolean values
#985
Move time rules to an extension
#1008
Bugfix/error annotate
#1002
Ref will not be converted if it is inside array passed to default
#989
Adds UUID Support
#947
.without(), runs before .empty()
#945
required() does not catch specific empty values
#960
Coercion doesn't run early enough
#949
Returning credit card number when is valid, fixes #948
#948
Credit Card returning null when valid
#934
Fix missing top-level methods
#933
Extended Joi does not contain certain top-level functions
#929
labels don't always get included in error messages with Joi.extend()
#928
Different error message for date().format()
#927
Check error messages in tests
#920
9.0.0 Release Notes
#918
number.multiple() enhancement - Issue #916
#916
number.multiple() throws exception for non-integer and ref values
#899
Treat empty string as null
#894
Add Joi.object().schema()
#893
Fix item ref. Closes #892
#892
References in array items() do not work
#880
Add synchronous extensibility
#874
any.label() significantly slows validation of large arrays
#860
Add the ability to specify a comparator for `array.unique()` for objects only
#859
custom compare for Joi.array().unique()
#856
Allow 1 to be true and 0 to be false.
#577
RFC: Joi plugins/extensions/custom functions
#919
joi.date().timestamp() failing validation for millisecond value
#909
Using empty in items on sparse array allows undefined elements.
#884
Synchronous schema.validate fails if called with options
#904
Add stripUnknownKeys option to Joi.validate
#903
stripUnknown: What is the expected behavior when validating nested data? (array)
#833
Proposal: string().truncate()
#379
Recursive schema (tree-like) validation
#900
When using reach, changing the label doesn't get applied, when an existing label is there
#883
Support error override per rule. Closes #882
#882
Support error override per rule
#851
Joi 8.x breaks describe().meta in alternatives
#837
Fix RegEx translation of IP6 BNF, where [] denotes an option
#834
TypeError: cannot delete property '0' of [object String]
#830
Return any.empty error for trimmed whitespace (fixes #827)
#828
Example for Array Schema Not Possible
#827
Unexpected Errors with Strings
#824
Description of assert modifying the original value
#823
8.0.0 Release Notes
#822
Problem with multiple when and conditional forbidden field
#763
Multiple alternatives with default
#735
Print string versions of NaN, Infinity and -Infinity - resolves #696
#696
NaN printed in cosole as null
#592
Some refs not converted in .describe()
#815
uri() fails RFC3986 4.2 relative reference URIs
#807
Question: Validate against sub-schema?
#565
Combine uppercase with valid
#812
Improve error message
#803
Label declaration/Validation
#800
Generate versioned API Reference link in README
#791
Date enhancements and support for Unix Timestamps
#789
Date() does not validate Unix timestamp with fractional seconds (decimals)
#787
Add a arity predicate for functions
#779
Throw custom Joi Errors
#774
Fix any.default() returns default object reference
#773
`Joi.validate()` returns default object reference instead of clone
#759
7.0.0 Release Notes
#756
es6. Closes #754. Closes 755
#755
Don't annotate non-object values
#754
ES6 style changes and node v4
#777
Fix any.default() returns default object reference
#753
Add default status 400 to error thrown by Joi.assert()
#747
removes leading "." from path at root object level
#740
Exception throw on undefined object key makes it difficult to track down issue
#745
Describe ordered arrays
#737
makes allow/valid/invalid not accept undefined #734
#734
Joi shouldn't allow Joi.any().valid(undefined).required()
#688
Toggable ordered flag for array to match items against input in order
#659
Allow treating arrays as objects
#730
Fix function properties validation. Closes #729
#729
Function keys validation converts function to object
#728
Allow functions to act as objects. Closes #727
#727
Allow function types to behave as object (e.g. have keys)
#721
The index of an incorrect array entry is returned instead of the field name
#710
Extending a schema
#708
add attempt function
#703
No dependency validation when object stripUnknown set to true
#702
add hapi to package.json keywords so joi is searchable
#693
Use hasOwnProperty from native object
#690
removes trailing "." from or path
#684
fix unknown nested key path
#683
Add the "noDefaults" option
#682
Validate without applying default values
#668
allow passing an error object as message to assert
#656
Updated regexp for more robust ISO 8601 validation
#649
Implementation of white space normalisation.
#648
Allow normalisation of white space
#586
[request] string().replace(pattern)
#660
stripUnkown on arrays removes valid objects when multiple items are defined
#654
Fix allowing context refs on some string, number and date methods
#629
help with `.or()`
#632
Nested whens don't work
#413
Create default [highly nested] object easily?
#628
Alternatives throw typeError when "is: null" is used
#627
Property is always required even when my When() condition isn't met.
#619
Add IP Address Validation and Separate IP and URI Logic to Files
#616
Add ignoreUndefined flag for rename()
#614
Error when .rename() from undefined
#611
Number compare functions allow decimal numbers
#610
Support for decimal numbers for min, max, less, greater number methods
#609
number min/max/greater/less do not allow decimal values
#597
Add reference support for String.min/max/length
#596
Add reference support for Number.min/max/greater/less
#583
do ref-able operations support referring to a list?
#560
References for Number comparisons?
#380
Comparison between fields
#580
Annotate fails on circular objects
#602
Validate multiple options with presence key in it
#601
Error: stripUnknown should be one of required, optional, forbidden, ignore
#600
Fix regression on unsafe string escaping in language
#593
.rename() does not work when new value is undefined
#589
Joi.array().items(...) error message changes
#585
No conversion is done inside Joi.array().items
#579
6.0.0 Release Notes
#578
respect stripUnknown in arrays
#572
add any.strip for objects and arrays
#569
Lost key after validation on assert
#567
Object with 'or', keys contains an array with a 'null' element
#561
how to concat array of objects inside an object property
#559
deprecate array.includes and array.excludes, use array.items and allow required and forbidden within
#557
Incomplete validation message
#555
add some additional guards and tests for #363
#553
Does array include allow nested object properties
#547
string hex characters only
#546
Really custom messages are impossible
#545
allow passing a method to .default(), for #363
#538
added number.multiple()
#536
Consider renaming 'valid' to 'enum' or an alias
#534
Bad behavior of Joi.object().concat()
#532
multipleOf method for Number?
#511
throw when invalid options are provided
#495
joi.array().includes path and errors mismatch
#488
Allow options to be passed to string.email().
#484
Helpful regexp message
#457
Add URI Validation
#363
support factory-function in .default() ?
#525
Strange behaviour with date + raw
#513
Make alternatives.describe more consistent
#510
Add new requiredKeys option specifically for object keys
#509
Option to validate a date format but not convert to a date object
#477
Support for references in `date.min()` and `date.max()`?
#404
Possible referencing date field to other date field?
#505
Convert date regex to date before comparison. Closes #503.
#503
Joi.date().iso() throws error when required() is used.
#502
Joi.array() modifies original array
#501
5.0.0 Release Notes
#498
array().single()
#497
array.unique doesn't validate duplicate dates
#494
Joi.number allows Infinity
#489
add missing semicolon
#486
array().includes() should not allow undefined
#485
Round number.precision if options.convert
#462
Return context with errors.
#381
Transformation support
#487
Code assertions requires () for exist tests
#481
Validate object constructor.
#408
Check if value is a RegEx
#480
Date "now" refers to date when schema was compiled
#478
Retain object reference when no rules specified
#476
Upgrade Lab
#470
Address internationalization issues.
#469
change implementation of creditcard to use string
#466
Named string regex patterns.
#465
implements credit card validation
#464
implements nand
#461
Add greater() and less() to number type. Closes #411
#456
correction for Describe with a "0" argument
#454
Describe with a "0" argument
#449
Enable to pass "now" in date.min and date.max
#446
Use Object.create in Any.clone to improve IE9 support
#440
Added any.label method
#435
Add format and iso to date type
#422
Credit card validation
#411
Number min/max exclusive or closed ranges respectively?
#407
ensure date does not occur in the past
#396
Negative-Integer-Strings are not properly converted to Date instances
#362
Support NAND
#437
Support optional message prefix in assert()
#434
Fix typo.
#433
Override default presence
#432
Set different default presence mode (required, forbidden)
#427
Added ability to validate the number of decimal places
#403
Add duplicates validation to array
#398
Upgrade lab 4.0
#397
Added check for global flag in pattern.
#389
Default Assert Message
#385
Path for array includes to contain key
#383
Describe object.pattern
#378
Removed unused sys import.
#366
Bug Hunt: empty object() + pattern() + unknown(false) fails to error
#359
Allow empty string after trim
#357
Cast milisecond strings to a date object
#355
Don't rename when there is nothing to rename.
#299
Sanitizing blanks
#360
Joi.assert()
#354
isemail 1.0
#351
Add Hoek isImmutable flag
#349
Support {{!key}} notation to securely encode unsafe values
#335
Recognize Joi errors
4.3.0
breaking changes
#341
Array includes fails if called multiple times
#340
Replace internal implementation of required/optional/forbidden
#339
when() option 'is' cannot be falsey
#337
alternatives().when() behaves inconsistently with any().when()
#336
concat() fails to remove valid/invalid values
#334
Bug hunt: Joi.any().when is not evaluated it its value is empty even if the when condition is fulfilled.
#332
Joi.any().when is not evaluated if empty
#326
Bug Hunt: unable to rename keys that are empty strings
#325
Bug Hunt: empty string key causes incorrect validation
#321
add uppercase, lowercase, and trim for strings
#317
Bug Hunt: invalid Date objects do not cause failure.
#313
Recursively describes the includes of array schemas #312
#312
Describe should also compile and describe array's rules
#311
Feature/meta
#310
Bug Hunt: email addresses longer than 254 should not be valid
#309
Bug Hunt: email addresses with a "local part" > 64 characters should not be validated
#293
Verify encoding type is string
#292
Add test to check for valid encoding param to binary
#288
Bug Hunt: valid IPv6 domain literals in email addresses fail validation
#282
Bug Hunt: double-quoted local-parts of email addresses cause validation failure
#261
Object key rules by patterns
#241
Thoughts on something like any.meta(obj)?
#220
string().lowercase() and string().uppsercase()
#330
Cannot override context
#329
Joi.forbidden() fails when added to an existing type
#328
Support references to external context
#324
Test for retaining ignored values
#323
Joi.forbidden()
#322
Make callback optional argument
#318
Convert tests to actual async style
#296
Allow valid to take buffer values
#291
remove extra var internals. Closes #290
#290
extra var internals in binary.js
#287
object.unknown()
#285
Fix to make object.and all-or-nothing - fixes #284
#284
Bug Hunt: object.and is supposed to be all-or-nothing
4.0.0
breaking changes
#278
Cleanup language file
#277
date() allows boolean value
#276
binary().encoding()
#275
Support when() on any()
#274
Undo #273, remove options from schema.validate()
#273
Remove module generic validate() and describe()
#272
Undo 268
#271
schema concat()
#270
Alt fails to report references
#269
Rename alternatives.attempt() with try()
#268
Move interfaces from func at root to const
#267
Add alternatives.attempt() to allow adding more schemas
#266
Make [] and alternatives() behave exactly the same
#265
object.and()
#264
Support references in default()
#263
object.assert()
#262
object.keys() append behavior
#260
Allow referencing the value of other keys in conditions
#259
Error messages should not include <root>
#258
Array should only convert string arrays
#257
Move dependencies (with,without, or, xor) to object level
#256
Keep input const and return modified value via validate callback
#255
Remove modify option
#254
4.0.0
#253
Validate callback, rename move to object
#252
Move rename() to object()
#250
Change validate() to return value via callback
#249
Alternatives bug fixes
#248
Move object() constructor args to keys() method
#247
unit() documentation method
#246
rename() applied incorrectly
#245
alternatives() fails to apply conversion when lower priority match has valid()
#244
alternatives() fails to apply conversion of matching schema
#243
alternatives() incorrectly allows null when no valids present
#239
Error inheritance is troublesome
#238
match() -> test()
#237
Support literal values as valid() condition
#234
testling support
#233
Add testling-ci badges
#226
Add support for binary type
#217
Incorrect ValidationError.annotated() output with abortEarly
#214
example() documentation method
#210
Add hostname matching to Joi.String
#206
Find full path to nested errors
#202
array() should set a specific detail.path
#196
Precompile schema
#194
Conditional rule based on value of another key
#192
64-bit limits in min()/max()/integer()
#191
Added support for buffer length
#345
Describe references as such
#343
Ref and Alternatives.when don't handle empty string keys
3.0.0
breaking changes
#231
Remove language file support
#230
3.0.0
#229
Bring coverage back to 100% after lab logical statement support
#228
hoek 2.0
#227
number allows string even with strict()
#224
Immutable schema objects. Closes #221
#221
Change object to immutable
#216
Change locale support to something that works with browserify.
#215
Enable all any() methods on array()
#201
Allows using any.rename() and any.default() together
#198
Allow language override directly via options
#197
Support for union types in schemas.
#195
Bring coverage back to 100% after lab fix
#187
Polluted request.payload by adding undefined field
#184
Throws error when field is missing and abortEarly=false
#183
set defaults #181
#181
setting defaults
#180
#179; add failing test for renames nested within array
#178
Embedded validators in Array().includes don't work
#177
Modify does not change internal values in array
#176
closes #175. missing required keys no longer throws.
#166
Required based on value on other key
#142
alternatives()
2.0.0
breaking changes
#232
2.0.0
#133
Array.includes() does not support more than 1 type
#128
with constraint doesn't seem to be respected
#126
Validate date supporting arbitrary format
#124
Array doesn't validate correctly if includes() uses valid()
#122
Update error messages to not have encoded characters
#121
Array is accepted as an Object type
#112
Remove Number.float()
#88
.valid() and .invalid() need a case-insensitive mode
#110
Adding support for special Any type
#107
.with and .without accept an array of args as well
#106
Add Type.Any
#105
Consistent usage of Array.isArray()
#95
Custom Error Messages
#25
Rewrite Readme.md
#23
Add validation tests for every type's methods with complex combinations
#20
String().valid doesn't invalidate bad values
#19
StringType.min(3) doesn't validate undefined correctly
#18
Adding tests to joi
clipboard