RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user to unmute
What it means
Thrown by `unmuteUserInRoom` when the subscription lookup succeeded but `Users.findOneByUsernameIgnoringCase(data.username)` returned no user (or a user document without a username). It means the room membership record exists while the corresponding user record does not — a data inconsistency such as a deleted user whose subscription lingered, or a username with no matching user document at all.
Source
Thrown at apps/meteor/server/meteor-methods/rooms/unmuteUserInRoom.ts:53
throw new Meteor.Error('error-invalid-room-type', `${room.t} is not a valid room type`, {
method: 'unmuteUserInRoom',
type: room.t,
});
}
const subscription = await Subscriptions.findOneByRoomIdAndUsername(data.rid, data.username, {
projection: { _id: 1 },
});
if (!subscription) {
throw new Meteor.Error('error-user-not-in-room', 'User is not in this room', {
method: 'unmuteUserInRoom',
});
}
const unmutedUser = await Users.findOneByUsernameIgnoringCase(data.username);
if (!unmutedUser?.username) {
throw new Meteor.Error('error-invalid-user', 'Invalid user to unmute', {
method: 'unmuteUserInRoom',
});
}
const fromUser = await Users.findOneById(fromId);
if (!fromUser) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'unmuteUserInRoom',
});
}
await callbacks.run('beforeUnmuteUser', { unmutedUser, fromUser }, room);
if (room.ro) {
await Rooms.unmuteReadOnlyUsernameByRoomId(data.rid, unmutedUser.username);
} else {
await Rooms.unmuteMutedUsernameByRoomId(data.rid, unmutedUser.username);
}View on GitHub (pinned to b2c16d5842)
Solutions
- Confirm the user exists first, e.g. `GET /api/v1/users.info?username=<username>`, before calling the method.
- If the user was deleted, remove the orphan subscription from the room instead of unmuting (membership cleanup).
- Resolve the username from the subscription record (`sub.u.username`) so renames/casing cannot diverge.
- Audit for orphan subscriptions (`Subscriptions` entries whose `u._id` has no `users` document) and clean them up.
Example fix
// before
Meteor.call('unmuteUserInRoom', { rid, username });
// after - confirm the user document exists first (REST)
const res = await fetch(`/api/v1/users.info?username=${encodeURIComponent(username)}`, {
headers: { 'X-Auth-Token': token, 'X-User-Id': uid },
});
if (!res.ok) {
// user record gone: clean up the orphan subscription instead of unmuting
return;
}
Meteor.call('unmuteUserInRoom', { rid, username }); Defensive patterns
Strategy: validation
Validate before calling
// verify both membership AND user existence before unmuting
const sub = await Subscriptions.findOneByRoomIdAndUsername(rid, username);
const user = sub && await Users.findOneByUsernameIgnoringCase(username);
if (sub && user?.username) {
await Meteor.callAsync('unmuteUserInRoom', { rid, username: user.username });
} Type guard
const hasUserRecord = async (username: string): Promise<boolean> => Boolean(await Users.findOneByUsernameIgnoringCase(username));
Try / catch
try {
await Meteor.callAsync('unmuteUserInRoom', { rid, username });
} catch (e: any) {
if (e?.error === 'error-invalid-user' && e?.reason === 'Invalid user to unmute') {
// user document missing: clean up the orphan subscription instead of retrying
}
} Prevention
- Delete users through the supported flows so their subscriptions are cleaned up atomically.
- Periodically audit for subscriptions whose u._id has no users document.
- Avoid creating test fixtures with subscriptions but no users.
When it happens
Trigger: Calling `unmuteUserInRoom` with a username whose subscription exists but whose user was deleted (user removed while muted, leaving an orphan subscription), or with a username that happens to match a subscription but has no user record (e.g. after a rename the old subscription key was kept).
Common situations: Partial user deletion that left subscriptions behind; workspaces imported or restored inconsistently; test fixtures that create subscriptions without matching users; automated scripts unmuting by username against stale data.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- user-not-found
- User must have a username to be banned from the room
- error-invalid-user
- error-invalid-room
- error-invalid-token
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/c59e6e95391e8534.
Report an issue: GitHub.