{"record":{"id":"f196fc59f5dd8189","repo":"RocketChat/Rocket.Chat","slug":"error-not-authorized-f196fc","errorCode":null,"errorMessage":"error-not-authorized","messagePattern":"error-not-authorized","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/lib/rooms.ts","lineNumber":27,"sourceCode":"\nexport async function findAdminRooms({\n\tuid,\n\tfilter,\n\ttypes = [],\n\tpagination: { offset, count, sort },\n}: {\n\tuid: string;\n\tfilter: string;\n\ttypes: Array<RoomType | 'discussions' | 'teams'>;\n\tpagination: { offset: number; count: number; sort: Sort };\n}): Promise<{\n\trooms: Array<Pick<IRoom, RoomAdminFieldsType> & IRoomAbacRedaction>;\n\tcount: number;\n\toffset: number;\n\ttotal: number;\n}> {\n\tif (!(await hasPermissionAsync(uid, 'view-room-administration'))) {\n\t\tthrow new Error('error-not-authorized');\n\t}\n\tconst name = filter?.trim();\n\tconst discussion = types?.includes('discussions');\n\tconst includeTeams = types?.includes('teams');\n\tconst typesToRemove = ['discussions', 'teams'];\n\tconst showTypes = Array.isArray(types) ? types.filter((type): type is RoomType => !typesToRemove.includes(type)) : [];\n\tconst options: FindOptions<IRoom> = {\n\t\tprojection: adminFields,\n\t\tskip: offset,\n\t\tlimit: count,\n\t};\n\n\tconst result = Rooms.findByNameOrFnameContainingAndTypes(name, showTypes, discussion, includeTeams, options);\n\n\tconst { cursor, totalCount } = result;\n\n\tconst [rooms, total] = await Promise.all([\n\t\tcursor","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/lib/rooms.ts#L9-L45","documentation":"findAdminRooms (apps/meteor/server/api/lib/rooms.ts) powers the admin room listing (rooms.adminRooms). It unconditionally requires the view-room-administration permission via hasPermissionAsync and throws plain Error 'error-not-authorized' otherwise — before any filtering by name/type ever runs. All failures at this site are permission failures, not data errors.","triggerScenarios":"GET /api/v1/rooms.adminRooms called with a token whose user lacks view-room-administration (regular member, bot, or custom role without admin rights).","commonSituations":"Admin-panel scrapers using a member account; custom 'moderator' role expected to see room admin pages but missing the permission; token confusion between admin and bot accounts.","solutions":["Use an administrator's credentials (or a user with the admin role)","Grant view-room-administration to the specific role in Administration > Permissions if moderators should list rooms","Switch to a non-admin endpoint (rooms.list) for basic room enumeration needs"],"exampleFix":"// before\nGET /api/v1/rooms.adminRooms (member token) -> error-not-authorized\n\n// after\nGET /api/v1/rooms.adminRooms (admin token)  // or grant view-room-administration to the role","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const { data } = await client.get('/api/v1/rooms.adminRooms', { params });\n} catch (e: any) {\n  if ((e?.response?.data?.error ?? '') === 'error-not-authorized') {\n    throw new ForbiddenError('token lacks view-room-administration — use an admin account');\n  }\n  throw e;\n}","preventionTips":["Reserve rooms.adminRooms calls for tokens you know are admin-issued","Check the caller's roles (users.info) before exposing admin room listings in tooling","Fallback for non-admin needs: rooms.list with membership scope"],"tags":["rest-api","admin","rooms","permissions","authorization"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}