{"record":{"id":"54711f9b7a238092","repo":"RocketChat/Rocket.Chat","slug":"error-param-not-provided","errorCode":"error-param-not-provided","errorMessage":"Query param \"role\" is required","messagePattern":"Query param \"role\" is required","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/roles.ts","lineNumber":190,"sourceCode":"\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t\t403: validateForbiddenErrorResponse,\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tconst { roomId, role } = this.queryParams;\n\t\t\tconst { offset, count = 50 } = await getPaginationItems(this.queryParams);\n\n\t\t\tconst projection = {\n\t\t\t\tname: 1,\n\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});","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/roles.ts#L172-L208","documentation":"Thrown by GET roles.getUsersInRole when the role query param is missing or falsy. The route requires the 'access-permissions' permission and uses the isRolesGetUsersInRoleProps query schema, but the action additionally enforces that role is non-empty here. Returns a structured Meteor.Error('error-param-not-provided', ...).","triggerScenarios":"GET /api/v1/roles.getUsersInRole with no role param, role=, or role='' (empty string).","commonSituations":"Client builds the query conditionally and omits role when a dropdown is empty; URL templating bug strips the param; copy-paste from a different endpoint.","solutions":["Always include a non-empty role query param when calling roles.getUsersInRole.","Use GET /api/v1/roles.list to discover valid role ids/names first.","Disable the submit action in the UI until a role is selected."],"exampleFix":"// before\nfetch(`/api/v1/roles.getUsersInRole${role ? `?role=${role}` : ''}`);\n\n// after\nif (!role) throw new Error('role is required');\nfetch(`/api/v1/roles.getUsersInRole?role=${encodeURIComponent(role)}`);","handlingStrategy":"validation","validationCode":"if (!role || role.trim() === '') throw new Error('role query param is required');\nfetch(`/api/v1/roles.getUsersInRole?role=${encodeURIComponent(role)}`);","typeGuard":"function hasRoleParam(qs: Record<string, unknown>): qs is { role: string } {\n  return typeof qs.role === 'string' && qs.role.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Disable submit until a role is chosen.","Fetch the role list first so callers select a valid id."],"tags":["roles","rest-api","validation","query-params"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}