Capítulo 19 de 39
setError(name, error, options?) manually attaches an error to a field (or a global root/server error), one field per call — the tool for surfacing server-side validation failures that RHF's own rules never ran.
{ type?, message?, types? } — type is an identifier ("required", "custom", "serverError") exposed as errors[name].type; message is the display string; types is a Record<string, string|boolean> for attaching several simultaneous messages to one field (pair with criteriaMode: "all" if you also want built-in/schema validation to populate types the same way).register rules re-validate and pass — setError doesn't outlast real validation for registered inputs.registered sticks around until you call clearErrors yourself.setError("root.serverError", { type: "400" }) — this kind of error does not persist across submissions the way a field error does.ref is actually attached to a real DOM element (not for custom-registered virtual inputs), and never works on a disabled input.isValid to false immediately: but that's a manual override, not a validation result — the next real validation pass (change, submit, trigger()) recomputes and can overwrite it.type, root, ref, types, message, form as actual field names — they collide with the internal FieldError/GlobalError shape.setError sets exactly one error per invocation — looping over a list of server-returned field errors and calling it once per entry is the standard pattern for multiple errors.setError("username", { type: "manual", message: "Dont Forget Your Username Should Be Cool!" })
setError("test", { type: "focus" }, { shouldFocus: true })
setError("lastName", { types: { required: "This is required", minLength: "This is minLength" } }) // needs criteriaMode: "all"
setError("root.serverError", { type: response.statusCode }) // global/server error, doesn't persist across submits
types, and a global server error.register's rules re-validating and passing clears it.type, root, message, etc.: collides with FieldError/GlobalError internals.setError once with an array expecting it to set multiple fields: it only ever sets one; loop it.setError is for errors RHF's own validation didn't produce (server responses, custom async checks outside validate) — expect it to be overwritten by real validation on registered fields.root.* is the dedicated namespace for global/server errors that shouldn't attach to a specific field and shouldn't persist submission-to-submission.types + criteriaMode: "all" is how a single field shows more than one simultaneous validation message.setError("root.serverError", ...) call.criteriaMode: "all" is what makes types populate from built-in/schema validation too, not just manual setError calls.