halo-dev/halo · warning · IllegalArgumentException
Email must not be blank
Error message
Email must not be blank
What it means
Thrown as IllegalArgumentException by DefaultSubscriberEmailResolver.ofEmail when the supplied email is null, empty, or whitespace-only. ofEmail builds an anonymous subscriber whose name encodes the email, so a blank email cannot produce a valid subscriber identity.
Source
Thrown at application/src/main/java/run/halo/app/notification/DefaultSubscriberEmailResolver.java:40
@RequiredArgsConstructor
public class DefaultSubscriberEmailResolver implements SubscriberEmailResolver {
private final ReactiveExtensionClient client;
@Override
public Mono<String> resolve(Subscription.Subscriber subscriber) {
var identity = UserIdentity.of(subscriber.getName());
if (identity.isAnonymous()) {
return Mono.fromSupplier(() -> getEmail(subscriber));
}
return client.fetch(User.class, subscriber.getName())
.filter(user -> user.getSpec().isEmailVerified())
.mapNotNull(user -> user.getSpec().getEmail());
}
@Override
public Subscription.Subscriber ofEmail(String email) {
if (StringUtils.isBlank(email)) {
throw new IllegalArgumentException("Email must not be blank");
}
var subscriber = new Subscription.Subscriber();
subscriber.setName(UserIdentity.anonymousWithEmail(email).name());
return subscriber;
}
String getEmail(Subscription.Subscriber subscriber) {
var identity = UserIdentity.of(subscriber.getName());
if (!identity.isAnonymous()) {
throw new IllegalStateException("The subscriber is not an anonymous subscriber");
}
return identity.getEmail()
.filter(StringUtils::isNotBlank)
.orElseThrow(() -> new IllegalStateException("The subscriber does not have an email"));
}
}
View on GitHub (pinned to d2f5165f9c)
Solutions
- Validate the email is non-blank and well-formed before calling ofEmail.
- Return a 400 to the client when the email field is missing.
- Default to a required-field check in the form/controller.
- Trim and reject empty strings upstream.
Example fix
// before
var sub = resolver.ofEmail(req.getEmail()); // email null
// after
if (!StringUtils.hasText(req.getEmail()) || !req.getEmail().contains("@")) {
return Mono.error(new ServerWebInputException("Valid email is required"));
}
var sub = resolver.ofEmail(req.getEmail().trim()); Defensive patterns
Strategy: validation
Validate before calling
if (!StringUtils.hasText(email) || !email.contains("@")) {
throw new ServerWebInputException("A valid email is required");
}
var sub = resolver.ofEmail(email.trim()); Type guard
static boolean isPlausibleEmail(String s) {
return s != null && !s.trim().isEmpty() && s.contains("@") && s.indexOf('@') > 0;
} Try / catch
try {
resolver.ofEmail(email);
} catch (IllegalArgumentException e) {
throw new ServerWebInputException("Email must not be blank", null, e);
} Prevention
- Validate email presence/format at the API boundary before resolving subscribers.
- Trim user input and reject empty values early.
- Use a shared email validator for all subscription endpoints.
When it happens
Trigger: Calling Subscription.Subscriber ofEmail(email) with a blank/null email string, e.g. from an unvalidated form field or an API request missing the email body.
Common situations: Notification subscription endpoints that don't validate the email; anonymous email-subscribe forms submitted empty; null passed programmatically due to a missing map key.
Related errors
- validation.error.email.pattern
- Email is required
- Locale "{locale}" cannot be used as it does not specify a la
- Failed to send email, please check your email configuration.
- Invalid attachment
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/b0a9a86fa57f1ca5.
Report an issue: GitHub.