RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

First 'error-invalid-user' guard in the /unarchiveroom slash command: it fires when the command's context carries no userId at all (null/undefined). Note the method field says 'archiveRoom' — a copy-paste artifact — but the throw site is unarchiveroom. Without a userId the command cannot check the 'unarchive-room' permission or attribute the action, so it aborts.

Source

Thrown at apps/meteor/server/slashcommands/unarchiveroom/server.ts:32

slashCommands.add({
	command: 'unarchive',
	callback: async function Unarchive({ params, message, userId }: SlashCommandCallbackParams<'unarchive'>): Promise<void> {
		let channel = params.trim();
		let room;

		if (channel === '') {
			room = await Rooms.findOneById(message.rid);
			if (room?.name) {
				channel = room.name;
			}
		} else {
			channel = channel.replace('#', '');
			room = await Rooms.findOneByName(channel);
		}

		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
		}

		const user = await Users.findOneById(userId, { projection: { username: 1, name: 1 } });
		if (!user || !isRegisterUser(user)) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
		}

		if (!room) {
			void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
				msg: i18n.t('Channel_doesnt_exist', {
					channelName: channel,
					lng: settings.get('Language') || 'en',
				}),
			});
			return;
		}

		if (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Ensure the command is run by a logged-in user (this.userId set) — type /unarchiveroom in an authenticated session.
  2. When invoking programmatically, pass a real userId: executeSlashCommand(command, params, message, userId).
  3. Check that the method binding that dispatches slash commands is not being called from a publish or non-user context.

Example fix

// before
if (!userId) {
  throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
}

// programmatic invocation fix
import { api } from 'meteor/rocketchat:api';
await api.executeSlashCommand('unarchiveroom', '#channel', { rid }, loggedInUserId);
Defensive patterns

Strategy: validation

Validate before calling

const userId = Meteor.userId();
if (!userId) {
  // do not invoke /unarchiveroom from an anonymous/system context
  throw new Error('Login required');
}
await Meteor.callAsync('slashCommand', { command: 'unarchiveroom', params: `#${channel}`, rid: message.rid });

Try / catch

try { await runUnarchive(); } catch (e) { if (isMeteorError(e, 'error-invalid-user')) { /* ensure an authenticated user context */ return; } throw e; }

Prevention

When it happens

Trigger: /unarchiveroom is invoked from a context where this.userId is absent: server-side invocation of the slash command with no authenticated user, a hook/bot calling executeSlashCommand without a userId, or an anonymous/offline connection reaching the method.

Common situations: Integrations or tests invoking slashCommands.execute programmatically and omitting the userId parameter; custom code triggering commands from system contexts.

Related errors


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