jquense/yup · error · TypeError

conditions must return a schema object

Error message

conditions must return a schema object

What it means

Condition.resolve() evaluates the condition's `is` predicate and returns the selected branch's resolved schema. After collapsing function branches (then/otherwise can be callbacks), the resulting value must still be a yup schema; if it is not, the condition cannot proceed and this TypeError is thrown. It guards against branches that return the wrong type or functions that forget to return anything.

Source

Thrown at src/Condition.ts:74

  resolve(base: TIn, options: ResolveOptions) {
    let values = this.refs.map((ref) =>
      // TODO: ? operator here?
      ref.getValue(options?.value, options?.parent, options?.context),
    );

    let schema = this.fn(values, base, options);

    if (
      schema === undefined ||
      // @ts-ignore this can be base
      schema === base
    ) {
      return base;
    }

    if (!isSchema(schema))
      throw new TypeError('conditions must return a schema object');

    return schema.resolve(options);
  }
}

export default Condition;

View on GitHub (pinned to ff31eee8a2)

Solutions

  1. Ensure every then/otherwise callback returns a yup schema: add `return s.required()` instead of just calling it.
  2. Check each branch value is a yup schema (created via yup.string(), yup.object(), etc.), not a plain value or object.
  3. Add a return-type annotation / TypeScript check on the condition builder so non-schema returns fail at compile time.

Example fix

// before
.when('other', { is: true, then: (s) => { s.required(); } })
// after
.when('other', { is: true, then: (s) => s.required() })
Defensive patterns

Strategy: type-guard

Validate before calling

import { isSchema } from 'yup';
branches.forEach((b) => { if (typeof b === 'function' && !isSchema(b())) throw new Error('condition branch must return a schema'); });

Type guard

const returnsSchema = (fn) => isSchema(fn());

Try / catch

try {
  schema.validateSync(value);
} catch (e) {
  if (e instanceof TypeError && e.message.includes('conditions must return a schema object')) {
    // fix the then/otherwise callback return value
  }
  throw e;
}

Prevention

When it happens

Trigger: then/otherwise given as a function that returns a non-schema value (or returns nothing), e.g. `.when('x', { is: true, then: (s) => { s.required(); } })` — the arrow returns undefined; or then/otherwise set to a plain value like `true`.

Common situations: Arrow functions with block bodies missing the return; returning a chained call on an object that is not a schema (typo like `yup.stringg()`); refactoring that replaced schemas with plain objects; TypeScript builds without strict types letting a wrong value through.

Related errors


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