{"record":{"id":"bd1aa371aece302f","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-bd1aa3","errorCode":"error-not-allowed","errorMessage":"Not Allowed","messagePattern":"Not Allowed","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/channels.ts","lineNumber":1735,"sourceCode":"\t\tconst { _id } = this.queryParams;\n\n\t\tif ((!query || Object.keys(query).length === 0) && !_id) {\n\t\t\treturn API.v1.failure('Invalid query');\n\t\t}\n\n\t\tconst filter = {\n\t\t\t...query,\n\t\t\t...(_id ? { _id } : {}),\n\t\t\tt: 'c',\n\t\t};\n\n\t\tconst room = await Rooms.findOne(filter as Record<string, any>);\n\t\tif (!room) {\n\t\t\treturn API.v1.failure('Channel does not exists');\n\t\t}\n\n\t\tif (!(await canAccessRoomAsync(room, this.user))) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not Allowed');\n\t\t}\n\n\t\tconst hidden = await getUsersHiddenFrom(this.userId);\n\n\t\tconst online: Pick<IUser, '_id' | 'username'>[] = filterHiddenUsers(\n\t\t\tawait Users.findUsersNotOffline({\n\t\t\t\tprojection: { username: 1 },\n\t\t\t}).toArray(),\n\t\t\thidden,\n\t\t);\n\n\t\tconst onlineInRoom = await Promise.all(\n\t\t\tonline.map(async (user) => {\n\t\t\t\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, {\n\t\t\t\t\tprojection: { _id: 1, username: 1 },\n\t\t\t\t});\n\t\t\t\tif (subscription) {\n\t\t\t\t\treturn {","sourceCodeStart":1717,"sourceCodeEnd":1753,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/e4b8178b205510181a96ceefee043d0abcd13e5a/apps/meteor/server/api/v1/channels.ts#L1717-L1753","documentation":"Meteor error error-not-allowed thrown by GET channels.online when the authenticated user cannot access the resolved channel (canAccessRoomAsync returns false for this.user). The channel exists and matches the query, but the caller has no membership/visibility rights to see who is online in it — public channels require nothing special, but the room found may be one the user cannot read.","triggerScenarios":"GET /api/v1/channels.online?_id=<channelId> (or with a query) where the user is not a member of a channel whose access rules exclude them (e.g. broadcast/teamsRoom restrictions, or the room matched by a loose query is not actually accessible).","commonSituations":"Bot tokens querying channels they were never invited to; query filter matching an unexpected room (missing t:'c' nuance aside, a broad query can resolve to a room the bot cannot see); user was kicked between list load and the online fetch.","solutions":["Have the calling user join the channel (channels.join) or get added, then retry","Verify access first with GET channels.info using the same credentials — it applies the same room-access rules","For bots, grant a role with the appropriate room visibility or use an admin-scoped token for read-only telemetry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"try {\n  await GET('/api/v1/channels.info', { roomId }); // same access rules\n} catch {\n  throw new Error('No access to channel; join it before querying online users');\n}","typeGuard":null,"tryCatchPattern":"try { await GET('/api/v1/channels.online', { _id: roomId }); } catch (e) {\n  if (e.error === 'error-not-allowed') { /* prompt join or use privileged token */ }\n}","preventionTips":["Grant bot tokens membership in the channels they monitor","Use narrow queries so channels.online resolves to the intended room"],"tags":["rest-api","channels","permissions","authorization","rocket-chat"],"backgroundTag":"insufficient-permissions","analyzedSha":"e4b8178b205510181a96ceefee043d0abcd13e5a","analyzedAt":"2026-09-08T13:24:24.891Z","contentChangedAt":"2026-09-08T13:24:24.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}