RocketChat/Rocket.Chat · warning · Meteor.Error

error-user-not-found

error-user-not-found

Error message

Inviter not found

What it means

Inside /invite, the message's userId is resolved with Users.findOneById(userId) to build the inviter; if the record is gone the command throws 'error-user-not-found' with method 'slashcommand-invite'. This is an internal invariant - the user by definition just sent the command - so hitting it means the session's uid no longer matches a live user document: the account was deleted concurrently, or clustered deployment replication lag hides the user from this node.

Source

Thrown at apps/meteor/server/slashcommands/invite/server.ts:95

				projection: { _id: 1, status: 1 },
			});
			if (subscription == null || isBannedSubscription(subscription)) {
				usersFiltered.push(user);
				continue;
			}
			const usernameStr = user.username as string;
			void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
				msg: i18n.t('Username_is_already_in_here', {
					username: usernameStr,
					lng: settings.get('Language') || 'en',
				}),
			});
		}

		const inviter = await Users.findOneById(userId);

		if (!inviter) {
			throw new Meteor.Error('error-user-not-found', 'Inviter not found', {
				method: 'slashcommand-invite',
			});
		}

		await Promise.all(
			usersFiltered.map(async (user) => {
				try {
					// TODO: Refactor this to return an error if some user fails to be added
					return await addUsersToRoomMethod(
						userId,
						{
							rid: message.rid,
							users: [user.username || ''],
						},
						inviter,
					);
				} catch (e: unknown) {
					if (isMeteorError(e)) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the uid still exists before dispatching user-triggered commands (or let the error surface as proof of a stale session)
  2. Terminate sessions and queued jobs of deleted users to stop stale commands
  3. In clustered deployments, ensure user lookups are consistent (read from primary) before processing commands
  4. Re-run the invite from a valid account; the invitee logic itself is unaffected

Example fix

// before
const inviter = await Users.findOneById(userId);
if (!inviter) throw new Meteor.Error('error-user-not-found', 'Inviter not found');

// after
const inviter = await Users.findOneById(userId);
if (!inviter) {
	logger.warn(`dropping /invite from vanished user ${userId}`);
	return; // stale session - do not process
}
Defensive patterns

Strategy: try-catch

Validate before calling

const inviter = await Users.findOneById(userId);
if (!inviter) {
	logger.warn(`dropping command from vanished user ${userId}`);
	return;
}

Try / catch

try {
	await handleInviteCommand(message);
} catch (err) {
	if (err instanceof Meteor.Error && err.error === 'error-user-not-found') return; // stale session; ignore
	throw err;
}

Prevention

When it happens

Trigger: User account deleted (or merged) after the message was sent but before the server processes the slash command; multi-node setups reading from a node where the users collection lags; system-injected or replayed messages carrying a stale uid.

Common situations: Admin deletes a spam account while its flood of /invite commands is still queued; federation or imports producing orphaned uids; test harnesses replaying recorded messages.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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