RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by the exported addUsersToRoomMethod() in apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:32 when the userId argument is falsy. Unlike the Meteor method wrappers, this helper takes the acting user ID as a parameter, so callers must supply it; the guard is a plain truthiness check before the rid validation runs.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:32

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		addUsersToRoom(data: { rid: string; users: string[] }): boolean;
	}
}

export const sanitizeUsername = (username: string) => {
	const isFederatedUsername = username.includes('@') && username.includes(':');
	if (isFederatedUsername) {
		return username;
	}

	return username.replace(/(^@)|( @)/, '');
};

export const addUsersToRoomMethod = async (userId: string, data: { rid: string; users: string[] }, user?: IUser): Promise<boolean> => {
	if (!userId) {
		throw new Meteor.Error('error-invalid-user', 'Invalid user', {
			method: 'addUsersToRoom',
		});
	}

	if (!Match.test(data.rid, String)) {
		throw new Meteor.Error('error-invalid-room', 'Invalid room', {
			method: 'addUsersToRoom',
		});
	}

	// Get user and room details
	const room = await Rooms.findOneById(data.rid);
	if (!room) {
		throw new Meteor.Error('error-invalid-room', 'Invalid room', {
			method: 'addUsersToRoom',
		});
	}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pass a real acting user ID: resolve it via Meteor.userId() in method contexts or accept it explicitly in jobs.
  2. Validate before calling: if (!userId) fail fast with your own error naming the missing parameter.
  3. Prefer the public REST endpoints POST /v1/channels.invite / POST /v1/groups.invite for integrations, which authenticate via headers.
  4. If you own the call site, make the parameter required in TypeScript (userId: string, not userId?: string) so the compiler catches omissions.

Example fix

// before
await addUsersToRoomMethod(Meteor.userId(), { rid, users });

// after
const uid = Meteor.userId();
if (!uid) throw new Error('no acting user; authenticate first');
await addUsersToRoomMethod(uid, { rid, users });
Defensive patterns

Strategy: validation

Validate before calling

const uid = Meteor.userId();
if (!uid) throw new Error('no acting user; authenticate first');
await addUsersToRoomMethod(uid, { rid, users });

Type guard

const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;

Try / catch

try {
  await addUsersToRoomMethod(userId, data);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {
    // caller passed a falsy userId: fix the call site, do not retry
  }
}

Prevention

When it happens

Trigger: Calling addUsersToRoomMethod('', rid, users) or with undefined/null userId — e.g. a caller that did Meteor.userId() ?? '' , a server job that lost its user context, or code passing the user object instead of its _id (object._id of a malformed object).

Common situations: Server-side automation invoking the helper outside a request context; refactors where the first parameter was changed from an IUser to a userId string and callers were not all updated; default-parameter code paths that pass undefined.

Related errors


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