RocketChat/Rocket.Chat · error
User without username
Error message
User without username
What it means
Rocket.Chat client guard in the Mute/Unmute user info action. Before POSTing to /v1/rooms.muteUser or /v1/rooms.unmuteUser, the action requires the target user's username because the REST endpoint only accepts a username. If the cached user document has no username, the onConfirm handler throws this local Error and the toast shows it instead of calling the API.
Source
Thrown at apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useMuteUserAction.tsx:72
const isMuted = getUserIsMuted(user, room, otherUserCanPostReadonly);
const roomName = room?.t && escapeHTML(roomCoordinator.getRoomName(room.t, room));
if (!room) {
throw Error('Room not provided');
}
const { roomCanMute } = getRoomDirectives({ room, showingUserId: user._id, userSubscription });
const mutedMessage = isMuted ? 'User__username__unmuted_in_room__roomName__' : 'User__username__muted_in_room__roomName__';
const muteUser = useEndpoint('POST', isMuted ? '/v1/rooms.unmuteUser' : '/v1/rooms.muteUser');
const muteUserOption = useMemo(() => {
const action = (): Promise<void> | void => {
const onConfirm = async (): Promise<void> => {
try {
if (!user.username) {
throw new Error('User without username');
}
await muteUser({ roomId: rid, username: user.username });
return dispatchToastMessage({
type: 'success',
message: t(mutedMessage, {
username: user.username,
roomName,
}),
});
} catch (error: unknown) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
closeModal();
}
};
View on GitHub (pinned to b2c16d5842)
Solutions
- Verify the user actually has a username: reload the room members list or check Admin > Users for the affected account and fix the account if the username is blank
- If you control the code, hide or disable the mute option when !user.username instead of throwing
- Reproduce with a fresh page load to rule out a stale subscription cache; if it persists, inspect the user document on the server
Example fix
// before
const onConfirm = async (): Promise<void> => {
if (!user.username) {
throw new Error('User without username');
}
await muteUser({ roomId: rid, username: user.username });
};
// after: hide the option entirely
const muteUserOption = useMemo(() => ({
content: isMuted ? t('Unmute') : t('Mute'),
isHidden: !user.username,
... Defensive patterns
Strategy: type-guard
Validate before calling
if (!user?.username) {
dispatchToastMessage({ type: 'error', message: 'User has no username' });
return;
} Type guard
const hasUsername = (u: { username?: string }): u is { username: string } =>
typeof u.username === 'string' && u.username.length > 0; Prevention
- Filter room members / user actions on !!username before rendering the Mute option
- Type the action's props so username is non-optional at the call site
- When subscribing to user data, project the username field explicitly
When it happens
Trigger: Opening a room member's info panel and clicking Mute/Unmute when the user object in the client cache has an empty/undefined username: accounts provisioned without a username (LDAP/OAuth mapping issues), users being deleted mid-session, or a minimongo cache from a subscription that projected the user without the username field.
Common situations: Username-generation settings producing empty usernames, stale client cache after admin edits, custom apps or integrations creating users without usernames, race between user deletion and the mute click.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid asset
- invalid-calendar-event
- error-invalid-role
- error-permission-not-found
- t('Message_deleting_blocked')
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/1589f996b899b912.
Report an issue: GitHub.