RocketChat/Rocket.Chat · error · Meteor.Error

error-empty-invite-list

error-empty-invite-list

Error message

Cannot invite if no valid users are provided

What it means

Thrown by POST groups.invite (non-federated branch) when getUserListFromParams(this.bodyParams) resolves to zero users. The helper looks for user identifiers in the body (userId / username / users arrays); if none of the provided identifiers match an existing user account, the list is empty and the invite is rejected before addUsersToRoomMethod runs. Federated rooms skip this path and invite by raw username.

Solutions

  1. Verify each invitee exists first via users/info (username or userId) and drop unknown ones from the list
  2. Use the exact body field names the endpoint reads - userId/username singular, or the array forms - check your SDK version's typings
  3. For not-yet-provisioned users, create the account (or wait for SSO provisioning) before inviting

Example fix

// before
await sdk.post('groups.invite', { roomId, users: ['alice', 'ghost-user'] }); // ghost-user unknown -> empty after filter

// after
const invitees = [];
for (const u of ['alice', 'ghost-user']) {
  try { await sdk.get('users.info', { username: u }); invitees.push(u); } catch { /* log skip */ }
}
if (invitees.length) await sdk.post('groups.invite', { roomId, users: invitees });
Defensive patterns

Strategy: validation

Validate before calling

async function resolveInvitees(usernames) {
  const found = [];
  for (const username of usernames) {
    try { await sdk.get('users/info', { username }); found.push({ username }); }
    catch (e) { logger.warn(`skipping unknown user ${username}`); }
  }
  if (!found.length) throw new Error('no existing users to invite');
  return found;
}

Type guard

const isNonEmptyUserList = (users: unknown): users is { username: string }[] =>
  Array.isArray(users) && users.length > 0 && users.every((u) => typeof u?.username === 'string' || typeof u?.userId === 'string');

Try / catch

try { await sdk.post('groups.invite', { roomId, users }); } catch (e) {
  if (e.error === 'error-empty-invite-list') { /* re-validate users via users/info, fix field names, drop ghosts */ }
}

Prevention

When it happens

Trigger: POST groups.invite { roomId, username: 'deleted.user' }; passing usernames of deactivated users; sending the wrong field name (e.g. 'userIds' when the API expects 'users'/'userId'); typo'd usernames; LDAP-synced usernames with different casing/spelling than assumed.

Common situations: Inviting users before their accounts exist (SSO provisioning lag); mixing userId and username field conventions between SDK versions; deactivated users lingering in onboarding lists.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/groups.ts:872

		const groupRoom = await Rooms.findOneByIdOrName(idOrName);
		const { _id: rid, t: type } = groupRoom || {};

		if (!rid || type !== 'p') {
			throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
		}

		// Federated rooms invite by raw username: the federated user record is created
		// lazily inside addUsersToRoomMethod, so we must not require it to exist locally yet.
		if (groupRoom && isRoomNativeFederated(groupRoom)) {
			const usernames = await getUsernameListFromParams(this.bodyParams);

			await addUsersToRoomMethod(this.userId, { rid, users: usernames }, this.user);
		} else {
			const users = await getUserListFromParams(this.bodyParams);

			if (!users.length) {
				throw new Meteor.Error('error-empty-invite-list', 'Cannot invite if no valid users are provided');
			}

			await addUsersToRoomMethod(this.userId, { rid, users: users.map((u) => u.username).filter(isTruthy) }, this.user);
		}

		const room = await Rooms.findOneById(rid, { projection: API.v1.defaultFieldsToExclude });

		if (!room) {
			throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
		}

		return API.v1.success({
			group: await composeRoomWithLastMessage(room, this.userId),
		});
	},
);

API.v1.post(

View on GitHub (pinned to e4b8178b20)