{"record":{"id":"1589f996b899b912","repo":"RocketChat/Rocket.Chat","slug":"user-without-username","errorCode":null,"errorMessage":"User without username","messagePattern":"User without username","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useMuteUserAction.tsx","lineNumber":72,"sourceCode":"\tconst isMuted = getUserIsMuted(user, room, otherUserCanPostReadonly);\n\tconst roomName = room?.t && escapeHTML(roomCoordinator.getRoomName(room.t, room));\n\n\tif (!room) {\n\t\tthrow Error('Room not provided');\n\t}\n\n\tconst { roomCanMute } = getRoomDirectives({ room, showingUserId: user._id, userSubscription });\n\n\tconst mutedMessage = isMuted ? 'User__username__unmuted_in_room__roomName__' : 'User__username__muted_in_room__roomName__';\n\n\tconst muteUser = useEndpoint('POST', isMuted ? '/v1/rooms.unmuteUser' : '/v1/rooms.muteUser');\n\n\tconst muteUserOption = useMemo(() => {\n\t\tconst action = (): Promise<void> | void => {\n\t\t\tconst onConfirm = async (): Promise<void> => {\n\t\t\t\ttry {\n\t\t\t\t\tif (!user.username) {\n\t\t\t\t\t\tthrow new Error('User without username');\n\t\t\t\t\t}\n\n\t\t\t\t\tawait muteUser({ roomId: rid, username: user.username });\n\n\t\t\t\t\treturn dispatchToastMessage({\n\t\t\t\t\t\ttype: 'success',\n\t\t\t\t\t\tmessage: t(mutedMessage, {\n\t\t\t\t\t\t\tusername: user.username,\n\t\t\t\t\t\t\troomName,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tdispatchToastMessage({ type: 'error', message: error });\n\t\t\t\t} finally {\n\t\t\t\t\tcloseModal();\n\t\t\t\t}\n\t\t\t};\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useMuteUserAction.tsx#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst onConfirm = async (): Promise<void> => {\n\tif (!user.username) {\n\t\tthrow new Error('User without username');\n\t}\n\tawait muteUser({ roomId: rid, username: user.username });\n};\n\n// after: hide the option entirely\nconst muteUserOption = useMemo(() => ({\n\tcontent: isMuted ? t('Unmute') : t('Mute'),\n\tisHidden: !user.username,\n\t...","handlingStrategy":"type-guard","validationCode":"if (!user?.username) {\n\tdispatchToastMessage({ type: 'error', message: 'User has no username' });\n\treturn;\n}","typeGuard":"const hasUsername = (u: { username?: string }): u is { username: string } =>\n\ttypeof u.username === 'string' && u.username.length > 0;","tryCatchPattern":null,"preventionTips":["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"],"tags":["rocket-chat","mute-user","client-validation","rest-api","user-object"],"backgroundTag":"missing-required-argument","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}