RocketChat/Rocket.Chat · error · Meteor.Error

error-not-allowed

error-not-allowed

Error message

Not Allowed

What it means

Thrown by GET groups.online when the caller cannot access the resolved private group: canAccessRoomAsync(room, this.user) returns false. groups.online lists online members of a group, and for private groups the caller must be a member (or hold access-granting permission/ABAC attributes). Note this endpoint returns 'Group does not exists' as a plain failure for a missing room, but a real room without access raises this error-not-allowed Meteor error.

Solutions

  1. Add the calling account to the group (groups.invite by an owner) or use an account with room-administration access rights
  2. Scope monitoring to rooms the service account is a member of; expose group membership lists to it explicitly
  3. Handle this error distinctly from 'Group does not exists' - it means access denied, not absent

Example fix

// before
const { online } = await botSdk.get('groups.online', { roomId: secretGroupId }); // bot not a member

// after
await ownerSdk.post('groups.invite', { roomId: secretGroupId, username: botUsername });
const { online } = await botSdk.get('groups.online', { roomId: secretGroupId });
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-flight with the same token: only poll groups.online for rooms the token can see
const visible = await sdk.get('rooms.info', { roomId }).catch(() => null);
if (!visible) throw new Error('token cannot access this group');

Try / catch

try {
  const { online } = await sdk.get('groups.online', { roomId });
} catch (e) {
  if (e.error === 'error-not-allowed') {
    // access denied for this private group: stop polling it with this token, alert operator
  } else if (e.errorType === 'error' || /does not exists/.test(String(e.message))) {
    // distinct branch: room genuinely missing
  }
}

Prevention

When it happens

Trigger: GET groups.online?roomId=<private group id> with a token whose user is not in that group; a bot account asked to monitor online users of an exclusive/secret group it was never invited to; access revoked (user kicked) while their client keeps polling presence.

Common situations: Presence dashboards built on service accounts that are not group members; permission model changes (ABAC rollout) silently revoking implicit access; monitoring tooling working for public channels but pointed at private groups.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-09-08). Data as JSON: /api/errors/54f8d873bd2dfac0. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/server/api/v1/groups.ts:1298

		const { _id } = this.queryParams;

		if ((!query || Object.keys(query).length === 0) && !_id) {
			return API.v1.failure('Invalid query');
		}

		const filter = {
			...query,
			...(_id ? { _id } : {}),
			t: 'p',
		};

		const room = await Rooms.findOne(filter as Record<string, any>);
		if (!room) {
			return API.v1.failure('Group does not exists');
		}

		if (!(await canAccessRoomAsync(room, this.user))) {
			throw new Meteor.Error('error-not-allowed', 'Not Allowed');
		}

		const hidden = await getUsersHiddenFrom(this.userId);

		const online: Pick<IUser, '_id' | 'username'>[] = filterHiddenUsers(
			await Users.findUsersNotOffline({
				projection: {
					username: 1,
				},
			}).toArray(),
			hidden,
		);

		const onlineInRoom = await Promise.all(
			online.map(async (user) => {
				const subscription = await Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, {
					projection: { _id: 1, username: 1 },
				});

View on GitHub (pinned to e4b8178b20)