{"record":{"id":"307d2f3962f1a4d4","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-roleid-307d2f","errorCode":"error-invalid-roleId","errorMessage":"error-invalid-roleId","messagePattern":"error-invalid-roleId","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/roles.ts","lineNumber":200,"sourceCode":"\t\t\t\tusername: 1,\n\t\t\t\temails: 1,\n\t\t\t\tavatarETag: 1,\n\t\t\t\tcreatedAt: 1,\n\t\t\t\t_updatedAt: 1,\n\t\t\t};\n\n\t\t\tif (!role) {\n\t\t\t\tthrow new Meteor.Error('error-param-not-provided', 'Query param \"role\" is required');\n\t\t\t}\n\t\t\tif (roomId && !(await hasPermissionAsync(this.user, 'view-other-user-channels'))) {\n\t\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed');\n\t\t\t}\n\n\t\t\tconst options = { projection: { _id: 1 } };\n\t\t\tconst roleData = await Roles.findOneById<Pick<IRole, '_id'>>(role, options);\n\n\t\t\tif (!roleData) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-roleId');\n\t\t\t}\n\n\t\t\tconst { cursor, totalCount } = await getUsersInRolePaginated(roleData._id, roomId, {\n\t\t\t\tlimit: count,\n\t\t\t\tsort: { username: 1 },\n\t\t\t\tskip: offset,\n\t\t\t\tprojection,\n\t\t\t});\n\n\t\t\tconst [users, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\t\t\treturn API.v1.success({ users, total });\n\t\t},\n\t)\n\t.post(\n\t\t'roles.delete',\n\t\t{\n\t\t\tauthRequired: true,","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/roles.ts#L182-L218","documentation":"Thrown by GET roles.getUsersInRole when Roles.findOneById(role, { projection: { _id: 1 } }) returns null. The role value passed does not match any role document. This is a bare Meteor.Error('error-invalid-roleId') with no human message, so clients must key off the error code.","triggerScenarios":"GET /api/v1/roles.getUsersInRole?role=<unknown> where role is a typo, a deleted role id, or a role name (this lookup is by id only, not by name).","commonSituations":"Caller passes a role name where an id is expected; role was deleted since the client last fetched the list; id copied from a different workspace.","solutions":["Resolve the role id from GET /api/v1/roles.list before listing users.","Confirm the value is the role _id, not the display name (e.g. use 'admin' _id, not 'Admin').","Invalidate cached role ids when this error appears and re-fetch the role list."],"exampleFix":"// before\nfetch(`/api/v1/roles.getUsersInRole?role=${roleName}`); // name, not id\n\n// after\nconst { roles } = await fetch('/api/v1/roles.list').then(r => r.json());\nconst role = roles.find(r => r.name === roleName);\nif (!role) throw new Error(`unknown role: ${roleName}`);\nfetch(`/api/v1/roles.getUsersInRole?role=${role._id}`);","handlingStrategy":"validation","validationCode":"// Resolve a valid role id before listing users\nconst { roles } = await fetch('/api/v1/roles.list').then(r => r.json());\nconst target = roles.find(r => r._id === role || r.name === role)?._id;\nif (!target) throw new Error(`unknown role: ${role}`);\nfetch(`/api/v1/roles.getUsersInRole?role=${encodeURIComponent(target)}`);","typeGuard":"function isRoleId(roles: { _id: string }[], value: string): boolean {\n  return roles.some(r => r._id === value);\n}","tryCatchPattern":null,"preventionTips":["Pass the role _id, not the display name, to this endpoint.","Invalidate cached role ids when this error appears."],"tags":["roles","rest-api","not-found","validation"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}