RocketChat/Rocket.Chat · critical · Meteor.Error

Email ${adminUser.emails![0].address} already exists

Error message

Email ${adminUser.emails![0].address} already exists

What it means

Startup guard in initialData.ts: when TEST_MODE is 'true' or 'api', Rocket.Chat seeds a well-known internal admin (rocketchat.internal.admin.test@rocket.chat). Before inserting, it verifies the email address is unused; if Users.findOneByEmailAddress finds a document, startup aborts with a Meteor.Error because the test fixture cannot be created safely. The error string doubles as the reason and the detail says the server can't run in test mode.

Source

Thrown at apps/meteor/server/startup/initialData.ts:234

				{
					address: 'rocketchat.internal.admin.test@rocket.chat',
					verified: true,
				},
			],
			status: UserStatus.OFFLINE,
			statusDefault: UserStatus.ONLINE,
			utcOffset: 0,
			active: true,
			type: 'user',
		};

		console.log(colors.green(`Name: ${adminUser.name}`));
		console.log(colors.green(`Email: ${adminUser.emails![0].address}`));
		console.log(colors.green(`Username: ${adminUser.username}`));
		console.log(colors.green(`Password: ${adminUser._id}`));

		if (await Users.findOneByEmailAddress(adminUser.emails![0].address)) {
			throw new Meteor.Error(`Email ${adminUser.emails![0].address} already exists`, "Rocket.Chat can't run in test mode");
		}

		if (!(await checkUsernameAvailability(adminUser.username!))) {
			throw new Meteor.Error(`Username ${adminUser.username} already exists`, "Rocket.Chat can't run in test mode");
		}

		await Users.create(adminUser);

		await Accounts.setPasswordAsync(adminUser._id, adminUser._id);

		await addUserRolesAsync(adminUser._id, ['admin']);

		if (settings.get('Show_Setup_Wizard') === 'pending') {
			(await Settings.updateValueById('Show_Setup_Wizard', 'in_progress')).modifiedCount &&
				void notifyOnSettingChangedById('Show_Setup_Wizard');
		}

		await addUserToDefaultChannels(adminUser as IUser, true);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Drop or rename the existing user holding rocketchat.internal.admin.test@rocket.chat before restarting in test mode.
  2. Point TEST_MODE runs at a clean database (fresh MongoDB or reset volume).
  3. Remove leftover fixture data: Users.removeById('rocketchat.internal.admin.test') in a mongo shell, then restart.

Example fix

# before: db still holds the fixture email
mongosh rock_chat --eval 'db.users.findOne({"emails.address":"rocketchat.internal.admin.test@rocket.chat"})'

# after: remove leftover fixture, then restart with TEST_MODE=true
mongosh rock_chat --eval 'db.users.remove({_id:"rocketchat.internal.admin.test"})'
Defensive patterns

Strategy: validation

Validate before calling

// Pre-start check: fixture email must be unused
const existing = await Users.findOneByEmailAddress('rocketchat.internal.admin.test@rocket.chat');
if (existing && TEST_MODE) { /* wipe fixture users or use a clean DB before boot */ }

Prevention

When it happens

Trigger: Starting the server with TEST_MODE=true/api against a database that already contains a user with the email rocketchat.internal.admin.test@rocket.chat (leftover fixture, or a real user that claimed that address).

Common situations: Re-running test mode on a persistent database from a previous test run; CI reusing a database volume without reset; someone manually creating that email address.

Related errors


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