RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-email
error-invalid-email
Error message
Invalid email
What it means
setEmail trims the email argument and throws error-invalid-email when the result is empty. This is pure presence validation: it fires before domain validation (validateEmailDomain) and availability checks, and no email-format regex runs here. Only an empty or whitespace-only string reaches this branch.
Solutions
- Require a non-empty, trimmed email in the calling form/API layer before invoking setEmail.
- Add basic format validation (regex) client-side so blank/garbage input never reaches the server.
- If email is optional in your flow, skip the setEmail call entirely instead of passing an empty string.
Example fix
// before
await setEmail(userId, req.body.email || '');
// after
const email = (req.body.email ?? '').trim();
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
throw new Meteor.Error('error-invalid-email', 'Invalid email');
}
await setEmail(userId, email); Defensive patterns
Strategy: validation
Validate before calling
const email = (rawEmail ?? '').trim();
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
throw new Meteor.Error('error-invalid-email', 'Invalid email', { field: 'email' });
}
await setEmail(userId, email); Type guard
const isValidEmail = (value: string): boolean => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value.trim());
Prevention
- Make the email field required in forms that feed setEmail.
- Trim user input before submission.
- Validate format client-side and server-side; never rely on the UI alone.
When it happens
Trigger: setEmail(userId, '') or setEmail(userId, ' ') — a form submitted with a blank email field, an optional field mapped straight into the call, or null coerced to empty string.
Common situations: Admin UI allowing blank email submissions; JSON payload with "email": ""; copy-paste whitespace-only values; migration scripts writing '' for users with no address.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/4ac0ea867ce9d2ff.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/lib/users/setEmail.ts:58
});
}
};
export const setEmail = async function (
userId: string,
email: string,
shouldSendVerificationEmail = true,
verified = false,
updater?: Updater<IUser>,
session?: ClientSession,
) {
email = email.trim();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { function: '_setEmail' });
}
if (!email) {
throw new Meteor.Error('error-invalid-email', 'Invalid email', { function: '_setEmail' });
}
await validateEmailDomain(email);
const user = await Users.findOneById(userId, { session });
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { function: '_setEmail' });
}
// User already has desired username, return
if (user?.emails?.[0] && user.emails[0].address === email) {
return user;
}
// Check email availability
if (!(await checkEmailAvailability(email))) {
throw new Meteor.Error('error-field-unavailable', `${email} is already in use :(`, {
function: '_setEmail',View on GitHub (pinned to b2c16d5842)