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
- Ensure every then/otherwise callback returns a yup schema: add `return s.required()` instead of just calling it.
- Check each branch value is a yup schema (created via yup.string(), yup.object(), etc.), not a plain value or object.
- 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
- Use concise arrow bodies for then/otherwise so the schema is returned implicitly.
- Never end a branch callback with a void call; always return the chained schema.
- Enable TypeScript return-type checking on condition builders.
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
- either `then:` or `otherwise:` is required for `when()` cond
- lazy() functions must return a valid schema
- `array.of()` sub-schema must be a valid yup schema not: ${pr
- ref must be a string, got:
- `${name}` must be a Date or a value that can be `cast()` to
AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31).
Data as JSON: /api/errors/a38abd571c4305d1.
Report an issue: GitHub.