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

  1. Strip any leading '@' and whitespace from the username before calling (the slash command expects a bare username)
  2. Verify the user exists first via Users.findOneByUsernameIgnoringCase(username) or GET /api/v1/users.info?username=...
  3. 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

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


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