</> setError: UseFormSetError
This function allows you to manually set an error on a field. You can call it multiple times to set errors on multiple fields.
Props
| Name | Type | Description |
|---|---|---|
name | string | input's name. |
error | { type?: string, message?: string, types?: MultipleFieldErrors } | type (optional) — An identifier for the error source (e.g. "required", "custom", "serverError"). Exposed as errors[name].type.message (optional) — The human-readable error message. Exposed as errors[name].message.types (optional) — A Record<string, string | boolean> that assigns multiple messages to a single field, keyed by error type (e.g. { required: "This is required", minLength: "Too short" }). Exposed as errors[name].types. Use this instead of message when you need to display more than one validation message for the same field simultaneously — set criteriaMode: "all" on the form if you also want built-in/schema validation to populate types the same way. |
| options | { shouldFocus?: boolean } | Should focus the input during setting an error. This only works when the input's reference is registered, it will not work for custom register as well. |
- This method will not persist the associated input error if the input passes
register's associated rules.register("registerInput", { minLength: 4 })setError("registerInput", { type: "custom", message: "custom message" })// validation will pass as long as minLength requirement pass - An error that is not associated with an input field will be persisted until cleared with
clearErrors. This behavior is only applicable for built-in validation at the field level.setError("notRegisteredInput", { type: "custom", message: "custom message" })// clearErrors() needs to be invoked manually to remove that custom error - Since v7.43.0 You can set a server or global error with
rootas the key. This type of error will not persist with each submission.
setError("root.serverError", {type: "400",})
shouldFocusdoesn't work when an input has been disabled.- This method will force
formState.isValidtofalse. However,isValidis always derived from the validation results of your registered inputs or schema. - Avoid using
type,root,ref,types,message, orformas field names — these collide with the internal shape ofFieldError/GlobalError.
Examples:
Single Error
import { useEffect } from "react"import { useForm } from "react-hook-form"type FormInputs = {username: string}const App = () => {const {register,handleSubmit,setError,formState: { errors },} = useForm<FormInputs>()const onSubmit = (data: FormInputs) => {console.log(data)}useEffect(() => {setError("username", {type: "manual",message: "Dont Forget Your Username Should Be Cool!",})}, [setError])return (<form onSubmit={handleSubmit(onSubmit)}><input {...register("username")} />{errors.username && <p>{errors.username.message}</p>}<input type="submit" /></form>)}
Multiple Errors
setError sets exactly one error per call. To set errors on multiple fields, call it once per field — typically in a loop over the server's error response.
import { useForm } from "react-hook-form"type FormInputs = {username: stringfirstName: string}const App = () => {const {register,handleSubmit,setError,formState: { errors },} = useForm<FormInputs>()const onSubmit = (data: FormInputs) => {console.log(data)}return (<form onSubmit={handleSubmit(onSubmit)}><label>Username</label><input {...register("username")} />{errors.username && <p>{errors.username.message}</p>}<label>First Name</label><input {...register("firstName")} />{errors.firstName && <p>{errors.firstName.message}</p>}<buttontype="button"onClick={() => {const inputs = [{type: "manual",name: "username",message: "Double Check This",},{type: "manual",name: "firstName",message: "Triple Check This",},]inputs.forEach(({ name, type, message }) => {setError(name, { type, message })})}}>Trigger Name Errors</button><input type="submit" /></form>)}
Single Field Errors
Use types (with criteriaMode: "all") to attach multiple validation messages to a single field at the same time. Each key in the object is an error-type identifier; each value is the message to display for that rule.
import { useEffect } from "react"import { useForm } from "react-hook-form"type FormInputs = {lastName: string}const App = () => {const {register,handleSubmit,setError,formState: { errors },} = useForm<FormInputs>({criteriaMode: "all",})const onSubmit = (data: FormInputs) => console.log(data)useEffect(() => {setError("lastName", {types: {required: "This is required",minLength: "This is minLength",},})}, [setError])return (<form onSubmit={handleSubmit(onSubmit)}><label>Last Name</label><input {...register("lastName")} />{errors.lastName && errors.lastName.types && (<p>{errors.lastName.types.required}</p>)}{errors.lastName && errors.lastName.types && (<p>{errors.lastName.types.minLength}</p>)}<input type="submit" /></form>)}
Server Error
import { useForm } from "react-hook-form";const App = () => {const { register, handleSubmit, setError, formState: { errors } } = useForm({criteriaMode: 'all',});const onSubmit = async () => {const response = await fetch(...)if (response.statusCode > 200) {setError('root.serverError', {type: response.statusCode,})}}return (<form onSubmit={handleSubmit(onSubmit)}><label>Last Name</label><input {...register("lastName")} />{errors.root.serverError.type === 400 && <p>server response message</p>}<button>submit</button></form>);};
Video
The following video explains the setError API in detail.
Thank you for your support
If you find React Hook Form to be useful in your project, please consider starring and supporting it.