RocketChat/Rocket.Chat · error · Meteor.Error
e.message
Error message
e.message
What it means
Dynamic rethrow: Accounts.createUserAsync rejected with a non-Meteor plain Error, so registerUser wraps e.message as the error text with NO stable error code. Typical origins are lower-level failures such as MongoDB duplicate-key (E11000 on users email/username) or custom accounts-validateNewUser hooks throwing plain Errors. Because there is no 'error-...' code, callers must match on the message.
Source
Thrown at apps/meteor/server/meteor-methods/users/registerUser.ts:116
await validateEmailDomain(formData.email);
const userData = {
email: trim(formData.email.toLowerCase()),
password: formData.pass,
...(formData.name?.trim() && { name: formData.name?.trim() }),
reason: formData.reason,
};
let userId;
try {
userId = await Accounts.createUserAsync(userData);
} catch (e) {
if (e instanceof Meteor.Error) {
throw e;
}
if (e instanceof Error) {
throw new Meteor.Error(e.message);
}
throw new Meteor.Error(String(e));
}
const reason = trim(formData.reason);
if (manuallyApproveNewUsers && reason) {
await Users.setReason(userId, reason);
}
try {
Accounts.sendVerificationEmail(userId, userData.email);
} catch (error) {
// throw new Meteor.Error 'error-email-send-failed', 'Error trying to send email: ' + error.message, { method: 'registerUser', message: error.message }
}
return userId;
};View on GitHub (pinned to b2c16d5842)
Solutions
- Inspect the wrapped message: 'E11000 duplicate key' means the email/username is taken - prompt the user and pre-check availability.
- Ensure custom onCreateUser/validateNewUser hooks throw Meteor.Error (with a code), not plain Error, so clients get a stable code.
- Disable the submit button while the call is in flight to prevent duplicate races.
Example fix
// before: hook throws a plain Error, surfaces as opaque code-less Meteor.Error
Accounts.validateNewUser(() => { throw new Error('bad domain'); });
// after: throw a coded Meteor.Error so registerUser rethrows it unchanged
Accounts.validateNewUser(() => {
throw new Meteor.Error('error-invalid-email-domain', 'Email domain not allowed');
}); Defensive patterns
Strategy: try-catch
Validate before calling
const taken = await checkUsernameAvailability(username); // e.g. GET /api/v1/users.info?username=...
const emailTaken = await checkEmailAvailability(email);
if (taken || emailTaken) return showInlineError('Username or email already in use'); Type guard
const isMeteorError = (e: unknown, code?: string): e is Meteor.Error => typeof e === 'object' && e !== null && 'error' in e && (code === undefined || (e as Meteor.Error).error === code);
Try / catch
try {
await Meteor.callAsync('registerUser', formData);
} catch (e) {
if (isMeteorError(e, 'error-user-registration-disabled')) { /* handled elsewhere */ }
// code-less errors come from createUserAsync wrapping: inspect the message
const detail = (e as Meteor.Error).reason ?? String((e as Meteor.Error).error);
if (/E11000 duplicate key/i.test(detail)) showInlineError('Email or username already registered');
else showError(detail);
} Prevention
- Pre-check email/username availability before submitting
- Make custom accounts hooks throw Meteor.Error with stable codes instead of plain Error
- Disable submit buttons while registration is in flight to avoid duplicate-race E11000
When it happens
Trigger: Registering with an email or username that collides at the Mongo index level (the accounts-base 'Email already exists' variant is a Meteor.Error and is rethrown unchanged; driver-level E11000 lands here); an accounts package hook or third-party plugin rejecting with `throw new Error(...)`.
Common situations: Double-submitted signup forms racing each other; custom username-normalization hooks throwing plain Errors; sharded/multi-instance deployments where the race window between check and insert widens.
Related errors
- String(e)
- error-user-registration-disabled
- error-user-registration-secret
- error-registering-provider
- error-importer-not-defined
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/b246253b2def2cff.
Report an issue: GitHub.