{"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/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/lib/roles/updateRole.ts#L2-L38","documentation":"Thrown by updateRole in updateRole.ts:20 when Roles.findOneById(roleId) returns null — the role being edited does not exist. MeteorError code 'error-invalid-roleId'.","triggerScenarios":"Calling updateRole with a roleId that was deleted, never existed, or is malformed. Concurrent deletion between load and save.","commonSituations":"Stale role-management UI; double-submit after the first call deleted-then-updated; CI using an outdated role id fixture.","solutions":["Refresh the role list and confirm the _id before editing.","Catch MeteorError 'error-invalid-roleId' and surface 'role no longer exists'.","Treat as idempotent no-op if the user's intent was deletion."],"exampleFix":"// before\nawait updateRole(roleId, roleData);\n\n// after\nif (!(await Roles.findOneById(roleId))) {\n  throw new Error('role vanished; refresh');\n}\nawait updateRole(roleId, roleData);","handlingStrategy":"validation","validationCode":"if (!(await Roles.findOneById(roleId))) throw new Error('role vanished');","typeGuard":"const roleExists = async (id: string) => Boolean(await Roles.findOneById(id, { projection: { _id: 1 } }));","tryCatchPattern":"try { await updateRole(roleId, roleData); }\ncatch (e) {\n  if (e?.code === 'error-invalid-roleId') { /* refresh list */ return; }\n  throw e;\n}","preventionTips":["Refetch the role before opening the edit form.","Avoid caching role ids in long-lived UI."],"tags":["roles","not-found","meteor-error"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}