RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Not Allowed
What it means
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'.
Source
Thrown at apps/meteor/server/api/v1/channels.ts:1729
const { _id } = this.queryParams;
if ((!query || Object.keys(query).length === 0) && !_id) {
return API.v1.failure('Invalid query');
}
const filter = {
...query,
...(_id ? { _id } : {}),
t: 'c',
};
const room = await Rooms.findOne(filter as Record<string, any>);
if (!room) {
return API.v1.failure('Channel does not exists');
}
if (!(await canAccessRoomAsync(room, this.user))) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
const online: Pick<IUser, '_id' | 'username'>[] = await Users.findUsersNotOffline({
projection: { username: 1 },
}).toArray();
const onlineInRoom = await Promise.all(
online.map(async (user) => {
const subscription = await Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, {
projection: { _id: 1, username: 1 },
});
if (subscription) {
return {
_id: user._id,
username: user.username,
};
}
}),View on GitHub (pinned to f9d3ec372b)
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.
Example fix
// before
const room = await Rooms.findOne(filter);
if (!room) {
return API.v1.failure('Channel does not exists');
}
if (!(await canAccessRoomAsync(room, this.user))) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
// after - distinguish unauthenticated from forbidden
if (!this.user) {
throw new Meteor.Error('error-unauthorized', 'Authentication required');
}
if (!(await canAccessRoomAsync(room, this.user))) {
throw new Meteor.Error('error-not-allowed', 'You do not have access to this channel');
} Defensive patterns
Strategy: validation
Validate before calling
// Confirm room access before listing online users
async function canViewChannelOnline(user, roomId) {
const room = await Rooms.findOneById(roomId);
if (!room) return false;
return canAccessRoomAsync(room, user);
} Type guard
function isAuthedUser(user) {
return Boolean(user) && typeof user._id === 'string';
} Try / catch
try {
await api.channels.online({ roomId });
} catch (e) {
if (e.error === 'error-not-allowed') {
promptJoinRoom(roomId); // user is not a member
return;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/bd1aa371aece302f.
Report an issue: GitHub.