{"record":{"id":"bd1aa371aece302f","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-bd1aa3","errorCode":"error-not-allowed","errorMessage":"Not Allowed","messagePattern":"Not Allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/channels.ts","lineNumber":1729,"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 online: Pick<IUser, '_id' | 'username'>[] = await Users.findUsersNotOffline({\n\t\t\tprojection: { username: 1 },\n\t\t}).toArray();\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 {\n\t\t\t\t\t\t_id: user._id,\n\t\t\t\t\t\tusername: user.username,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}),","sourceCodeStart":1711,"sourceCodeEnd":1747,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/channels.ts#L1711-L1747","documentation":"Thrown by the channels online/listing endpoint when canAccessRoomAsync(room, this.user) returns false for the resolved channel. The room exists (a missing room returns a failure string instead), but the calling user lacks access. Uses Meteor.Error with code 'error-not-allowed'.","triggerScenarios":"Calling the channel online-users endpoint for a channel the user is not a member of, or when not authenticated at all (this.user is null/undefined).","commonSituations":"Querying presence in a private channel from a non-member; session token expired so this.user is null; integration test using the wrong user fixture.","solutions":["Ensure the calling user is a member of the channel (or has view-logs/view-room privileges).","Authenticate with a valid token so this.user is populated.","If presence data must be exposed, grant the relevant role a permission like view-outside-room."],"exampleFix":"// before\nconst room = await Rooms.findOne(filter);\nif (!room) {\n  return API.v1.failure('Channel does not exists');\n}\nif (!(await canAccessRoomAsync(room, this.user))) {\n  throw new Meteor.Error('error-not-allowed', 'Not Allowed');\n}\n\n// after - distinguish unauthenticated from forbidden\nif (!this.user) {\n  throw new Meteor.Error('error-unauthorized', 'Authentication required');\n}\nif (!(await canAccessRoomAsync(room, this.user))) {\n  throw new Meteor.Error('error-not-allowed', 'You do not have access to this channel');\n}","handlingStrategy":"validation","validationCode":"// Confirm room access before listing online users\nasync function canViewChannelOnline(user, roomId) {\n  const room = await Rooms.findOneById(roomId);\n  if (!room) return false;\n  return canAccessRoomAsync(room, user);\n}","typeGuard":"function isAuthedUser(user) {\n  return Boolean(user) && typeof user._id === 'string';\n}","tryCatchPattern":"try {\n  await api.channels.online({ roomId });\n} catch (e) {\n  if (e.error === 'error-not-allowed') {\n    promptJoinRoom(roomId); // user is not a member\n    return;\n  }\n  throw e;\n}","preventionTips":["Ensure the user is a member of the channel before calling online-presence endpoints.","Send a valid auth token so this.user is populated.","Distinguish 'channel missing' (returns failure) from 'no access' (throws) in your client."],"tags":["channels","authorization","room-access","presence"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}