RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by the /join slash command when Users.findOneById returns no user document for the authenticated userId. It is a defensive guard: a valid Meteor userId should always map to a Users record, so hitting it means the user was deleted, deactivated mid-request, or the users collection is inconsistent with the login token.

Source

Thrown at apps/meteor/server/slashcommands/join/server.ts:47

					lng: settings.get('Language') || 'en',
				}),
			});
			return;
		}

		const subscription = await Subscriptions.findOneByRoomIdAndUserId(room._id, userId, {
			projection: { _id: 1 },
		});

		if (subscription) {
			throw new Meteor.Error('error-user-already-in-room', 'You are already in the channel', {
				method: 'slashCommands',
			});
		}

		const user = await Users.findOneById(userId);
		if (!user) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', {
				method: 'slashCommands',
			});
		}
		await Room.join({ room, user });
	},
	options: {
		description: 'Join_the_given_channel',
		params: '#channel',
		permission: 'view-c-room',
	},
});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the Users document exists for the current userId (Users.findOneById) before invoking join flows.
  2. If it was deleted, log the user out and re-authenticate with a valid account.
  3. Audit for partial deletions or restores that dropped the users collection.
  4. In custom code calling slashCommands programmatically, pass a userId known to exist.

Example fix

// before
const user = await Users.findOneById(userId);
if (!user) {
  throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'slashCommands' });
}

// caller-side guard
const user = Meteor.user();
if (!user) {
  // re-authenticate instead of running /join
}
Defensive patterns

Strategy: validation

Validate before calling

const user = await Meteor.callAsync('getUser', Meteor.userId());
if (!user) { /* session is stale: log out and re-authenticate */ }

Type guard

const hasValidUser = (u: unknown): u is IUser =>
  Boolean(u) && typeof (u as IUser)._id === 'string' && Array.isArray((u as IUser).roles);

Try / catch

try { await Meteor.callAsync('slashCommand', { command: 'join', ... }); } catch (e) { if (isMeteorError(e, 'error-invalid-user')) { Meteor.logout(); /* re-login */ return; } throw e; }

Prevention

When it happens

Trigger: /join executes after the userId's Users document was removed (user deletion raced the command), or the account exists in Meteor's login service but its Users row is missing (partial migration, restored database without users collection).

Common situations: Running the command from a session whose user was just deleted by an admin; database restored from backup with mismatched collections; test harnesses forging userIds that have no user document.

Related errors


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