{"record":{"id":"295790eb79541317","repo":"RocketChat/Rocket.Chat","slug":"username-is-required","errorCode":null,"errorMessage":"Username is required","messagePattern":"Username is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/views/admin/permissions/UsersInRole/hooks/useRemoveUserFromRole.tsx","lineNumber":30,"sourceCode":"\troleDescription,\n}: {\n\trid?: IRoom['_id'];\n\troleId: IRole['_id'];\n\troleName: IRole['name'];\n\troleDescription: IRole['description'];\n}) => {\n\tconst { t } = useTranslation();\n\n\tconst setModal = useSetModal();\n\tconst dispatchToastMessage = useToastMessageDispatch();\n\tconst queryClient = useQueryClient();\n\n\tconst removeUserFromRoleEndpoint = useEndpoint('POST', '/v1/roles.removeUserFromRole');\n\n\tconst handleRemove = useStableCallback((username: IUserInRole['username']) => {\n\t\tconst remove = async () => {\n\t\t\ttry {\n\t\t\t\tif (!username) throw new Error('Username is required');\n\n\t\t\t\tawait removeUserFromRoleEndpoint({ roleId, username, scope: rid });\n\t\t\t\tdispatchToastMessage({ type: 'success', message: t('User_removed') });\n\t\t\t\tqueryClient.invalidateQueries({\n\t\t\t\t\tqueryKey: ['getUsersInRole'],\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tdispatchToastMessage({ type: 'error', message: error });\n\t\t\t} finally {\n\t\t\t\tsetModal(null);\n\t\t\t}\n\t\t};\n\n\t\tsetModal(\n\t\t\t<GenericModal variant='danger' onConfirm={remove} onCancel={() => setModal(null)} confirmText={t('Delete')}>\n\t\t\t\t{t('The_user_s_will_be_removed_from_role_s', { username, role: roleDescription || roleName })}\n\t\t\t</GenericModal>,\n\t\t);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/client/views/admin/permissions/UsersInRole/hooks/useRemoveUserFromRole.tsx#L12-L48","documentation":"Client-side guard in the UsersInRole admin panel: when removing a user from a role, the handler receives the row's username and throws a plain Error 'Username is required' if it is falsy before calling POST /v1/roles.removeUserFromRole. The caught error is shown as a toast. It signals a UI/data defect — a role-membership row without a username — rather than a server problem.","triggerScenarios":"Clicking 'remove' on a users-in-role table row whose username field is empty/undefined (data fetched from GET /v1/roles.getUsersInRole lacking username), or a programmatic call of handleRemove with no argument.","commonSituations":"Broken/incomplete REST payload for users-in-role (custom fields stripping username); corrupted membership documents; regressions in the table component passing the wrong property.","solutions":["Inspect the getUsersInRole response for the offending row and fix the underlying data so username is present.","Verify the component passes username (not name/userId) into handleRemove.","If memberships without usernames are legitimate in your deployment, guard the UI earlier and hide the remove action for such rows."],"exampleFix":"// before\nif (!username) throw new Error('Username is required');\n\n// after: prevent the broken row from offering 'remove'\nconst canRemove = Boolean(row.username);\n<Table.Cell>{canRemove ? <RemoveButton username={row.username} /> : null}</Table.Cell>","handlingStrategy":"type-guard","validationCode":"const rows = (await getUsersInRole({ roleId })).users;\nconst removable = rows.filter((r) => Boolean(r.username));","typeGuard":"const hasUsername = (row: IUserInRole): row is IUserInRole & { username: string } =>\n  typeof row.username === 'string' && row.username.length > 0;","tryCatchPattern":"try { await handleRemove(row.username); } catch (e) { if ((e as Error).message === 'Username is required') { /* fix the row data, then retry */ return; } throw e; }","preventionTips":["Validate API payloads include username before rendering action buttons.","Hide destructive actions for rows missing required identity fields.","Add schema validation on the getUsersInRole response in dev builds."],"tags":["rocket-chat","admin-ui","react","permissions"],"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-14T05:17:10.506Z"}