- Published on
Fixing YUP Conditional Validation: 'Branch is Not a Function' Error
- Authors
- Name
- Ripal & Zalak
Fixing YUP Conditional Validation: "Branch is Not a Function" Error
When working with the YUP validation library in JavaScript or TypeScript, you might encounter the error:
TypeError: branch is not a function at Condition.fn
This issue commonly arises when using conditional validation with the when
method after updating to newer versions of YUP. In this blog post, we’ll explore the root cause and provide practical solutions to fix this error.
🛠 The Problem
Consider the following schema:
const schema = yup.object().shape({
userRole: yup.string().required('User Role is required'),
permissions: yup
.object()
.shape()
.when('userRole', {
is: (role) => role === 'admin',
then: () =>
yup.object({
accessLevel: yup
.string()
.oneOf(['full', 'partial'], 'Invalid access level')
.required('Access level is required'),
}),
otherwise: () =>
yup.object({
accessLevel: yup.string().oneOf(['none'], "Only 'none' is allowed for non-admins"),
}),
}),
})
This code throws the "branch is not a function" error due to changes in YUP's syntax for when
conditions. The then
and otherwise
properties now require a function that returns a schema instead of directly using a schema.
✅ The Solution
Modify your code to wrap the schema inside a function. Here's the corrected schema:
const schema = yup.object().shape({
userRole: yup.string().required('User Role is required'),
permissions: yup
.object()
.shape()
.when('userRole', {
is: (role) => role === 'admin',
then: () =>
yup.object({
accessLevel: yup
.string()
.oneOf(['full', 'partial'], 'Invalid access level')
.required('Access level is required'),
}),
otherwise: () =>
yup.object({
accessLevel: yup.string().oneOf(['none'], "Only 'none' is allowed for non-admins"),
}),
}),
})
Key Change:
- Replace:With:
then: yup.object({ ... })
then: () => yup.object({ ... })
This applies to otherwise
conditions as well.
🌟 Common Scenarios and Fixes
when
Validation
1. Basic For simple conditional validations, wrap the then
schema in a function:
const schema = yup.object().shape({
isVerified: yup.boolean().required(),
profile: yup.object().when('isVerified', {
is: true,
then: () =>
yup.object({
email: yup.string().email('Invalid email').required('Email is required'),
}),
otherwise: () =>
yup.object({
phone: yup.string().min(10, 'Invalid phone number').required('Phone is required'),
}),
}),
})
2. Multi-Field Conditional Validation
When working with multiple fields in the condition:
const schema = yup.object().shape({
country: yup.string().required('Country is required'),
address: yup.object().when(['country'], {
is: (country) => country === 'US',
then: () =>
yup.object({
state: yup.string().required('State is required for US'),
zipCode: yup.string().matches(/\d{5}/, 'Invalid zip code'),
}),
otherwise: () =>
yup.object({
province: yup.string().required('Province is required'),
}),
}),
})
🤔 FAQs
Q1: Why did this error start occurring?
YUP introduced breaking changes in version 1.x
, where the then
and otherwise
methods now require functions that return schemas. This is more consistent with its functional programming design.
Q2: Can I fix this without upgrading my code?
The easiest fix is to update your code to the new syntax. If you cannot update, consider downgrading to a pre-1.0
version of YUP.
Q3: What if I’m using TypeScript?
Ensure your when
conditions and schemas have proper typings. TypeScript compatibility often improves with the updated syntax.