RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
In dry-run mode Mailer.sendMail looks up the account whose email equals 'from' (Users.findOneByEmailAddress) to render one sample message; if no user matches it throws error-invalid-user. The dry-run therefore requires the from-address to belong to an existing local user account.
Source
Thrown at apps/meteor/server/lib/notifications/mail-messages/functions/sendMail.ts:43
}): Promise<void> {
Mailer.checkAddressFormatAndThrow(from, 'Mailer.sendMail');
if (body.indexOf('[unsubscribe]') === -1) {
throw new Meteor.Error('error-missing-unsubscribe-link', 'You must provide the [unsubscribe] link.', {
function: 'Mailer.sendMail',
});
}
let userQuery: Filter<any> = { 'mailer.unsubscribed': { $exists: 0 } };
if (query) {
userQuery = { $and: [userQuery, EJSON.parse(query)] };
}
if (dryrun) {
const user = await Users.findOneByEmailAddress(from);
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
function: 'Mailer.sendMail',
});
}
const email = `${user.name} <${user.emails?.[0].address}>`;
const html = placeholders.replace(body, {
unsubscribe: Meteor.absoluteUrl(
generatePath('mailer/unsubscribe/:_id/:createdAt', {
_id: user._id,
createdAt: user.createdAt?.getTime().toString() || '',
}),
),
name: user.name,
email,
});
SystemLogger.debug({
msg: 'Sending email',View on GitHub (pinned to b2c16d5842)
Solutions
- Set 'from' to the email of an existing user (typically your admin account) when using dryrun: true
- Verify first with Users.findOneByEmailAddress(from)
- Alternatively drop dryrun and constrain recipients with a narrow 'query' instead
Example fix
// before
await Mailer.sendMail({ from: 'noreply@external.com', subject, body, dryrun: true });
// after
const admin = await Users.findOneByEmailAddress('admin@yourdomain.tld');
if (!admin) throw new Error('pick a from address owned by a real user');
await Mailer.sendMail({ from: admin.emails[0].address, subject, body, dryrun: true }); Defensive patterns
Strategy: validation
Validate before calling
const user = await Users.findOneByEmailAddress(from);
if (!user) {
// dryrun needs a from address owned by an existing user
throw new Error('from address has no matching user');
}
await Mailer.sendMail({ from, subject, body, dryrun: true }); Try / catch
try {
await Mailer.sendMail({ from, subject, body, dryrun: true });
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-invalid-user') {
// switch 'from' to an address belonging to a real user and retry the dry run
} else throw err;
} Prevention
- Use your own admin account's address as 'from' when testing with dryrun
- Keep the sending address attached to a dedicated user account
When it happens
Trigger: Mailer.sendMail({ from: 'marketing@external.com', dryrun: true, ... }) where the address is not attached to any Rocket.Chat user; the matching user was deleted; a typo or case mismatch against the stored email.
Common situations: Testing the Mailer with an external or no-reply address; organization changed its from-address without a matching user account; admin testing after user cleanup.
Related errors
- invalid email
- error-missing-unsubscribe-link
- error-user-not-in-room
- error-invalid-user
- error-invalid-user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/3d9cfc7ff16c2624.
Report an issue: GitHub.