jquense/yup · error · TypeError

`test` is a required parameters

Error message

`test` is a required parameters

What it means

Schema.test() accepts either an options object or positional (name, message, test) arguments, and the `test` option must be the actual predicate function. This TypeError is thrown when opts.test is not a function after argument normalization.

Source

Thrown at src/schema.ts:784

  test(...args: any[]) {
    let opts: TestConfig;

    if (args.length === 1) {
      if (typeof args[0] === 'function') {
        opts = { test: args[0] };
      } else {
        opts = args[0];
      }
    } else if (args.length === 2) {
      opts = { name: args[0], test: args[1] };
    } else {
      opts = { name: args[0], message: args[1], test: args[2] };
    }

    if (opts.message === undefined) opts.message = locale.default;

    if (typeof opts.test !== 'function')
      throw new TypeError('`test` is a required parameters');

    let next = this.clone();
    let validate = createValidation(opts);

    let isExclusive =
      opts.exclusive || (opts.name && next.exclusiveTests[opts.name] === true);

    if (opts.exclusive) {
      if (!opts.name)
        throw new TypeError(
          'Exclusive tests must provide a unique `name` identifying the test',
        );
    }

    if (opts.name) next.exclusiveTests[opts.name] = !!opts.exclusive;

    next.tests = next.tests.filter((fn) => {
      if (fn.OPTIONS!.name === opts.name) {

View on GitHub (pinned to ff31eee8a2)

Solutions

  1. Pass the test function: .test('name', 'message', value => boolean)
  2. Use the options-object form: .test({ name, message, test: fn })
  3. Check that the referenced function is defined and imported
  4. Use .required() instead if the goal was a built-in check, not a custom test

Example fix

// before
yup.string().test('isUpper', 'must be uppercase');
// after
yup.string().test('isUpper', 'must be uppercase', v => v === v?.toUpperCase());
Defensive patterns

Strategy: validation

Validate before calling

if (typeof testFn !== 'function') throw new Error('test() requires a predicate function');
schema.test({ name: 'myTest', message: 'msg', test: testFn });

Type guard

function isTestOptions(o: unknown): o is { name?: string; message?: string; test: (v: any) => boolean } {
  return typeof (o as any)?.test === 'function';
}

Try / catch

try { schema.test(opts as any); } catch (e) { if (/`test` is a required/.test(e.message)) console.warn('skipping invalid test'); else throw e; }

Prevention

When it happens

Trigger: Calling .test('myCheck') with only a name, .test('name', 'message') with no test fn, passing a non-function (e.g. a boolean or undefined) as the test argument, or an options object missing the `test` key.

Common situations: Forgetting to supply the predicate when only customizing the message; passing a named reference to an undefined function; refactoring that removed the test function but left the arguments.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31). Data as JSON: /api/errors/388826a8a8fe70e1. Report an issue: GitHub.