{"record":{"id":"df3fa74c74070445","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-roleid","errorCode":"error-invalid-roleId","errorMessage":"This role does not exist","messagePattern":"This role does not exist","errorType":"exception","errorClass":"MeteorError","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/lib/roles/updateRole.ts","lineNumber":20,"sourceCode":"import type { IRole } from '@rocket.chat/core-typings';\nimport { Roles } from '@rocket.chat/models';\n\nimport { isValidRoleScope } from '../../../../lib/roles/isValidRoleScope';\nimport { notifyOnRoleChangedById } from '../../../../server/lib/notifyListener';\n\ntype UpdateRoleOptions = {\n\tbroadcastUpdate?: boolean;\n};\n\nexport const updateRole = async (\n\troleId: IRole['_id'],\n\troleData: Omit<IRole, '_id' | '_updatedAt'>,\n\toptions: UpdateRoleOptions = {},\n): Promise<IRole> => {\n\tconst role = await Roles.findOneById(roleId);\n\n\tif (!role) {\n\t\tthrow new MeteorError('error-invalid-roleId', 'This role does not exist');\n\t}\n\n\tif (role.protected && ((roleData.name && roleData.name !== role.name) || (roleData.scope && roleData.scope !== role.scope))) {\n\t\tthrow new MeteorError('error-role-protected', 'Role is protected');\n\t}\n\n\tif (roleData.name) {\n\t\tconst otherRole = await Roles.findOneByName(roleData.name, { projection: { _id: 1 } });\n\t\tif (otherRole && otherRole._id !== role._id) {\n\t\t\tthrow new MeteorError('error-duplicate-role-names-not-allowed', 'Role name already exists');\n\t\t}\n\t} else {\n\t\troleData.name = role.name;\n\t}\n\n\tif (roleData.scope) {\n\t\tif (!isValidRoleScope(roleData.scope)) {\n\t\t\tthrow new MeteorError('error-invalid-scope', 'Invalid scope');","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/lib/roles/updateRole.ts#L2-L38","documentation":"updateRole starts by resolving the target with Roles.findOneById(roleId); if nothing is found it throws MeteorError('error-invalid-roleId', 'This role does not exist'). The value must be the role document's _id, not the role name - passing a name (or a stale/deleted id) lands on this throw.","triggerScenarios":"Calling updateRole with a roleId that was deleted in another session, a malformed id, or the role's name accidentally supplied in the id field.","commonSituations":"An admin edits a role in a tab while another admin deletes it, so the form posts a now-dead id; scripts hard-coding role ids that differ across environments (staging vs production); payload builders confusing name and _id.","solutions":["Re-fetch the roles list and use the current _id of the role you intend to change.","If you only know the name, resolve it first: Roles.findOneByName(name) and use its _id.","Refresh role admin UIs before saving edits so stale ids are not submitted."],"exampleFix":"// before\nawait updateRole('moderator', { description: 'Can moderate' }); // name passed as id -> throws\n\n// after\nconst role = await Roles.findOneByName('moderator');\nif (!role) throw new MeteorError('error-invalid-roleId', 'This role does not exist');\nawait updateRole(role._id, { description: 'Can moderate' });","handlingStrategy":"validation","validationCode":"const role = await Roles.findOneById(roleId);\nif (!role) {\n\t// stale or wrong id; re-fetch the roles list and use a current _id instead of calling updateRole\n}","typeGuard":null,"tryCatchPattern":"try {\n\tawait updateRole(roleId, roleData);\n} catch (e: any) {\n\tif (e?.error === 'error-invalid-roleId') return notFound('role', roleId); // 404 to the client\n\tthrow e;\n}","preventionTips":["Always resolve roles by name (Roles.findOneByName) when only the name is known, then use the returned _id.","Refresh role admin views before saving edits so deleted roles are not targeted.","Never hard-code role ids across environments; ids are per-database."],"tags":["roles","permissions","entity-not-found","enterprise"],"backgroundTag":"entity-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}