halo-dev/halo · error · ServerWebInputException
validation.error.email.pattern
validation.error.email.pattern
Error message
validation.error.email.pattern
What it means
Thrown as a ServerWebInputException (HTTP 400) with code 'validation.error.email.pattern' by UserEndpoint.sendEmailVerificationCode. The EmailVerifyRequest body is run through bean validation; if the email field fails its @Email/@Pattern constraint, the message 'validation.error.email.pattern' is thrown. The string is intentionally an i18n code, not human text, so the frontend can localize it.
Source
Thrown at application/src/main/java/run/halo/app/core/endpoint/console/UserEndpoint.java:324
/**
* Payload for verifying an email address by code.
*
* @param password current password of the authenticated user
* @param code email verification code
*/
public record VerifyCodeRequest(
@Schema(requiredMode = REQUIRED) String password,
@Schema(requiredMode = REQUIRED, minLength = 1) String code) {}
private Mono<ServerResponse> sendEmailVerificationCode(ServerRequest request) {
var emailMono = request.bodyToMono(EmailVerifyRequest.class)
.switchIfEmpty(Mono.error(() -> new ServerWebInputException("Request body is required.")))
.doOnNext(emailReq -> {
var bindingResult = ValidationUtils.validate(emailReq, validator, request.exchange());
if (bindingResult.hasErrors()) {
// only email field is validated
throw new ServerWebInputException("validation.error.email.pattern");
}
})
.map(EmailVerifyRequest::email)
.map(String::toLowerCase);
return Mono.zip(emailMono, getAuthenticatedUserName())
.flatMap(tuple -> {
var email = tuple.getT1();
var username = tuple.getT2();
return Mono.just(username)
.transformDeferred(sendEmailVerificationCodeRateLimiter(username))
.flatMap(u -> emailVerificationService.sendVerificationCode(username, email))
.onErrorMap(RequestNotPermitted.class, RateLimitExceededException::new);
})
.then(ServerResponse.ok().build());
}
<T> RateLimiterOperator<T> verificationEmailRateLimiter(String username) {
String rateLimiterKey = "verify-email-" + username;View on GitHub (pinned to d2f5165f9c)
Solutions
- Validate the email client-side (RFC-ish regex or HTML5 type=email) before posting the request.
- Send a well-formed email string in the JSON body 'email' field, e.g. 'user@example.com'.
- Map the response code 'validation.error.email.pattern' to a localized user-facing message in the UI.
Example fix
// before
// { "email": "foo@@bar" }
// after
// { "email": "user@example.com" } Defensive patterns
Strategy: validation
Validate before calling
// validate email before calling sendEmailVerificationCode
private static final Pattern EMAIL =
Pattern.compile("^[^@\s]+@[^@\s]+\.[^@\s]+$");
if (!EMAIL.matcher(email).matches()) {
showUserError("Enter a valid email address");
return;
} Prevention
- Validate email format in the UI (HTML5 type=email + regex) before submit.
- Map response code 'validation.error.email.pattern' to a localized message.
When it happens
Trigger: POST /apis/api.console.halo.run/v1alpha1/users/-/send-email-verification-code with a JSON body whose 'email' is missing, empty, or malformed (e.g. 'foo@@bar', 'not-an-email', 'user@'). ValidationUtils.validate reports errors on the email field.
Common situations: Frontend validation bypassed; user typed an invalid email; a migration/import script sends raw unvalidated emails; testing with placeholder strings like 'test' or 'N/A'.
Related errors
- Email is required
- validation.error.password.size
- Name is required
- validation.error.password.size
- Invalid file type, only jar is supported
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/d80f821130ac60c6.
Report an issue: GitHub.