RocketChat/Rocket.Chat · error
You are the last owner. Please set new owner before banning
Error message
You are the last owner. Please set new owner before banning the user.
What it means
The target holds the 'owner' role in this room and Roles.countUsersInRole('owner', room._id) === 1 - banning them would orphan the room, so the server refuses until another owner exists. This protects channels and private groups from becoming ownerless; the message text tells the moderator exactly what to do.
Source
Thrown at apps/meteor/server/lib/banUserFromRoom.ts:53
const subscription = await Subscriptions.findOneByRoomIdAndUserId(data.rid, bannedUser._id, {
projection: { _id: 1, status: 1 },
});
if (!subscription) {
throw new Error('User is not in this room');
}
// Cannot ban a user who is already banned
if (isBannedSubscription(subscription)) {
throw new Error('User is already banned from this room');
}
// Cannot ban the last owner
if (await hasRoleAsync(bannedUser._id, 'owner', room._id)) {
const numOwners = await Roles.countUsersInRole('owner', room._id);
if (numOwners === 1) {
throw new Error('You are the last owner. Please set new owner before banning the user.');
}
}
await banUserFromRoom(data.rid, bannedUser, fromUser);
return true;
};
View on GitHub (pinned to b2c16d5842)
Solutions
- Promote another member to owner first (channels.addOwner / groups.addOwner with roomId and userId), then retry the ban
- Or have the owner transfer ownership and step out of the room before any ban
- Surface the actionable message ('set new owner before banning') directly in the moderation UI
Example fix
// before
await POST '/api/v1/rooms.banUser' { roomId, username: 'last.owner' }; // throws
// after
await POST '/api/v1/channels.addOwner' { roomId, userId: otherMemberId }; // or groups.addOwner for private rooms
await POST '/api/v1/rooms.banUser' { roomId, username: 'last.owner' }; Defensive patterns
Strategy: validation
Validate before calling
const { roles } = await GET '/api/v1/channels.roles' { roomId }; // or groups.roles
const owners = roles.filter((r) => r.roles.includes('owner'));
if (owners.length === 1 && owners[0].u.username === username) {
// promote another member first (channels.addOwner) before banning
} Type guard
const isSoleOwner = (roles: { u: { username: string }; roles: string[] }[], username: string): boolean =>
roles.filter((r) => r.roles.includes('owner')).length === 1 &&
roles.some((r) => r.roles.includes('owner') && r.u.username === username); Try / catch
try {
await POST '/api/v1/rooms.banUser' { roomId, username };
} catch (e) {
if (String(e.message).includes('last owner')) {
// run addOwner for another member, then retry the ban once
} else {
throw e;
}
} Prevention
- Check the room's owner list before offering ban on owners
- Keep at least two owners in active rooms to avoid the deadlock
- Automate promote-then-ban sequences instead of manual retries
When it happens
Trigger: Banning the sole owner of a channel; the owners list shrank (other owners left or transferred) making the target the last one; /ban against a room creator who never promoted anyone else.
Common situations: Cleaning up inactive creator accounts; reorganizing room ownership during team migrations.
Related errors
- Not allowed
- The required "roomId" or "roomName" param provided does not
- User is not in this room
- User is already banned from this room
- error-remove-last-owner
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/fc14e357135a6904.
Report an issue: GitHub.