RocketChat/Rocket.Chat · error · Meteor.Error

error-you-are-last-owner

error-you-are-last-owner

Error message

You are the last owner. Please set new owner before leaving the room.

What it means

Thrown by 'removeUserFromRoom' when the user being removed holds the 'owner' role in the room and a role count shows they are the only owner (Roles.countUsersInRole('owner', room._id) === 1). Rocket.Chat refuses to kick the last owner to prevent rooms becoming ownerless, where nobody could moderate, edit settings, or manage membership. A new owner must be set before this user can be removed.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/removeUserFromRoom.ts:82

	await Room.beforeUserRemoved(room);

	if (!canKickAnyUser) {
		const subscription = await Subscriptions.findOneByRoomIdAndUserId(data.rid, removedUser._id, {
			projection: { _id: 1 },
		});
		if (!subscription) {
			throw new Meteor.Error('error-user-not-in-room', 'User is not in this room', {
				method: 'removeUserFromRoom',
			});
		}
	}

	if (await hasRoleAsync(removedUser._id, 'owner', room._id)) {
		const numOwners = await Roles.countUsersInRole('owner', room._id);

		if (numOwners === 1) {
			throw new Meteor.Error('error-you-are-last-owner', 'You are the last owner. Please set new owner before leaving the room.', {
				method: 'removeUserFromRoom',
			});
		}
	}

	try {
		await Apps.self?.triggerEvent(AppEvents.IPreRoomUserLeave, room, removedUser, fromUser);
	} catch (error: any) {
		if (error.name === AppsEngineException.name) {
			throw new Meteor.Error('error-app-prevented', error.message);
		}

		throw error;
	}

	await callbacks.run('beforeRemoveFromRoom', { removedUser, userWhoRemoved: fromUser }, room);

	const deletedSubscription = await Subscriptions.removeByRoomIdAndUserId(data.rid, removedUser._id);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Promote another existing member to owner first (Meteor method 'addUserToRole'/'setOwner', or REST POST /api/v1/channels.addOwner with roleId/permission), then retry the removal.
  2. If the goal is to delete the room entirely, archive/delete the room instead of kicking its last owner.
  3. For self-removal flows, have the owner use leaveRoom after transferring ownership (same rule applies).
  4. In bulk scripts, skip or defer rooms where the target is the last owner, and surface them for manual ownership transfer.

Example fix

// before
await removeUserFromRoomMethod(fromId, { rid, username: target }); // target is last owner -> error-you-are-last-owner

// after
if ((await Roles.countUsersInRole('owner', rid)) === 1 && (await hasRoleAsync(targetId, 'owner', rid))) {
  await Meteor.callAsync('addUserToRole', 'owner', [otherMemberUsername], rid); // set new owner first
}
await removeUserFromRoomMethod(fromId, { rid, username: target });
Defensive patterns

Strategy: validation

Validate before calling

// Server-side: ensure the target is not the last owner before kicking
const isOwner = await hasRoleAsync(targetId, 'owner', rid);
const ownerCount = await Roles.countUsersInRole('owner', rid);
if (isOwner && ownerCount === 1) {
  const successor = await Subscriptions.findOneByRoomIdAndUserId(rid, successorId, { projection: { _id: 1 } });
  if (!successor) throw new Error('Pick an existing member as the new owner');
  await Meteor.callAsync('addUserToRole', 'owner', [successorUsername], rid);
}
await removeUserFromRoomMethod(fromId, { rid, username: targetUsername });

Try / catch

try {
  await Meteor.callAsync('removeUserFromRoom', { rid, username });
} catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-you-are-last-owner') {
    throw new Error(`Promote another owner for room ${rid} before removing ${username}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Kicking the sole owner of a channel/group; demoting other owners first and then attempting to remove the remaining one; automated cleanup scripts that remove all members including the last owner; attempting to kick a team-creator who never transferred ownership.

Common situations: Offboarding scripts that purge a workspace admin/owner from every room; admins trying to delete a test room by first kicking its creator; rooms where other owners left over time leaving exactly one.

Related errors


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