RocketChat/Rocket.Chat · error · Error
User not found
Error message
User not found
What it means
Thrown by unbanUserFromRoom when Users.findOneByUsernameIgnoringCase(data.username) returns null, i.e. no user exists with the given username. The lookup is case-insensitive, so casing is not the issue; the username simply does not exist (typo, deleted user, or an id passed where a username was expected).
Source
Thrown at apps/meteor/server/lib/unbanUserFromRoom.ts:30
}
const room = await Rooms.findOneById(data.rid);
if (!room || !(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.BAN, fromId))) {
throw new Error('Not allowed');
}
const fromUser = await Users.findOneById(fromId);
if (!fromUser) {
throw new Error('Invalid user');
}
if (!(await canAccessRoomAsync(room, fromUser))) {
throw new Error('The required "roomId" or "roomName" param provided does not match any group');
}
const bannedUser = await Users.findOneByUsernameIgnoringCase(data.username);
if (!bannedUser) {
throw new Error('User not found');
}
await executeUnbanUserFromRoom(data.rid, bannedUser, fromUser);
return true;
};
View on GitHub (pinned to b2c16d5842)
Solutions
- Strip any leading '@' and whitespace from the username before calling (the slash command expects a bare username)
- Verify the user exists first via Users.findOneByUsernameIgnoringCase(username) or GET /api/v1/users.info?username=...
- If the banned user was deleted, remove the stale ban record instead of unbanning
Example fix
// before
await unbanUserFromRoom(fromId, { rid, username: `@${name}` });
// after
const cleanUsername = username.replace(/^@/, '').trim();
const target = await Users.findOneByUsernameIgnoringCase(cleanUsername, { projections: { _id: 1 } });
if (!target) throw new Error(`No user named ${cleanUsername}`);
await unbanUserFromRoom(fromId, { rid, username: cleanUsername }); Defensive patterns
Strategy: validation
Validate before calling
const clean = rawUsername.replace(/^@/, '').trim();
const target = await Users.findOneByUsernameIgnoringCase(clean, { projections: { _id: 1 } });
if (!target) throw new Error(`No user named ${clean}`);
await unbanUserFromRoom(fromId, { rid, username: clean }); Try / catch
try {
await unbanUserFromRoom(fromId, { rid, username });
} catch (e) {
if (e instanceof Error && e.message === 'User not found') {
return { ok: false, reason: 'username-unknown' };
}
throw e;
} Prevention
- Always pass the bare username, never the _id or an @mention
- Trim and strip @ before submitting
- Offer username autocomplete from real users in moderation UIs
When it happens
Trigger: /unban slash command with a misspelled or already-deleted username; passing the user's _id or an '@mention' token (with the leading @) instead of the raw username; REST unban call with a username whose account was removed after the ban was created.
Common situations: Banned user deletes their account before the unban; UI forwarding the display name instead of the username; copy-paste introducing trailing whitespace or an @ prefix.
Related errors
- error-invalid-user
- User must have a username to be banned from the room
- error-invalid-username
- error-not-allowed
- error-blocked-username
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/39ba309ee6fbc459.
Report an issue: GitHub.