RocketChat/Rocket.Chat · error · Error

error-invalid-email

error-invalid-email

Error message

error-invalid-email

What it means

Thrown by `sendOfflineMessage` when the destructured `email` field of the offline message data is falsy. The offline email needs a reply-to address, so the payload is rejected before any template/DNS work — a plain required-field gate, distinct from error 918's domain-validity check.

Source

Thrown at apps/meteor/server/lib/omnichannel/messages.ts:37

const dnsResolveMx = util.promisify(dns.resolveMx);

type OfflineMessageData = {
	message: string;
	name: string;
	email: string;
	department?: string;
	host?: string;
};

export async function sendOfflineMessage(data: OfflineMessageData) {
	if (!settings.get('Livechat_display_offline_form')) {
		throw new Error('error-offline-form-disabled');
	}

	const { message, name, email, department, host } = data;

	if (!email) {
		throw new Error('error-invalid-email');
	}

	const emailMessage = `${message}`.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2');

	let html = '<h1>New livechat message</h1>';
	if (host && host !== '') {
		html = html.concat(`<p><strong>Sent from:</strong><a href='${host}'> ${host}</a></p>`);
	}
	html = html.concat(`
			<p><strong>Visitor name:</strong> ${name}</p>
			<p><strong>Visitor email:</strong> ${email}</p>
			<p><strong>Message:</strong><br>${emailMessage}</p>`);

	const fromEmail = settings.get<string>('From_Email').match(/\b[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}\b/i);

	let from: string;
	if (fromEmail) {
		from = fromEmail[0];

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Make the email field required and validated (non-empty, basic format) in the form before submission
  2. If building the payload in code, assert `data.email` is a non-empty string first
  3. For API consumers, return a 400-style validation message instead of surfacing the raw error

Example fix

// before
await sendOfflineMessage({ message, name, email: '' });

// after
if (!email || !/.+@.+\..+/.test(email)) {
  throw new Error('A valid email is required');
}
await sendOfflineMessage({ message, name, email });
Defensive patterns

Strategy: validation

Validate before calling

if (!data.email || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(data.email)) {
  throw new Error('Email is required');
}
await sendOfflineMessage(data);

Type guard

const hasContactEmail = (d: { email?: string }): boolean =>
  typeof d.email === 'string' && d.email.trim().length > 0;

Try / catch

try {
  await sendOfflineMessage(data);
} catch (e) {
  if (e instanceof Error && e.message === 'error-invalid-email') {
    // mark the email input as required in the form
  }
}

Prevention

When it happens

Trigger: Submitting the offline form with an empty email input — the widget/API did not enforce the field client-side, or the payload was constructed programmatically without an `email` key.

Common situations: Custom offline-form frontends that drop the email input or mark it optional; middleware stripping unknown/empty fields; users submitting with whitespace-only input that survives naive checks.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/57c56b996103685c. Report an issue: GitHub.