RocketChat/Rocket.Chat · error · Meteor.Error

error-not-allowed

error-not-allowed

Error message

Not allowed

What it means

loadNextMessages authorizes via canAccessRoomIdAsync(rid, fromId): if the room does not exist or the logged-in user has no access to it (not a member of the private channel, not a DM participant), it throws error-not-allowed 'Not allowed'. This guard runs after the user and rid checks passed, so hitting it means identity and rid were fine but room access was denied.

Source

Thrown at apps/meteor/server/meteor-methods/messages/loadNextMessages.ts:35

Meteor.methods<ServerMethods>({
	async loadNextMessages(rid, end, limit = 20) {
		check(rid, String);
		check(limit, Number);

		if (!Meteor.userId()) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', {
				method: 'loadNextMessages',
			});
		}

		if (!rid) {
			throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'loadNextMessages' });
		}

		const fromId = Meteor.userId();

		if (!fromId || !(await canAccessRoomIdAsync(rid, fromId))) {
			throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'loadNextMessages' });
		}

		let records;
		if (end) {
			records = await Messages.findVisibleByRoomIdAfterTimestamp(rid, end, true, {
				sort: {
					ts: 1,
				},
				limit,
			}).toArray();
		} else {
			records = await Messages.findVisibleByRoomId(rid, {
				sort: {
					ts: 1,
				},
				limit,
			}).toArray();
		}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Check the Subscriptions cache for rid before calling
  2. Invalidate cached room state on kick/room-deleted events
  3. Catch error-not-allowed and show an inline 'no access' state instead of crashing

Example fix

// before
const { messages } = await Meteor.callAsync('loadNextMessages', rid, end, limit);

// after
const sub = Subscriptions.findOne({ rid });
if (!sub) {
  return { messages: [] }; // caller has no access to this room
}
const { messages } = await Meteor.callAsync('loadNextMessages', rid, end, limit);
Defensive patterns

Strategy: try-catch

Validate before calling

const sub = Subscriptions.findOne({ rid });
if (!sub) {
  // no membership — skip paging newer messages
}

Try / catch

try {
  const { messages } = await Meteor.callAsync('loadNextMessages', rid, end, limit);
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-not-allowed') {
    return { messages: [] }; // access revoked — stop paging this room
  }
  throw error;
}

Prevention

When it happens

Trigger: Paging newer messages for a room the caller was removed from; a rid of a deleted room (canAccessRoomIdAsync fails); deep links into a private channel the user never joined.

Common situations: Stale subscriptions after being kicked; room deleted while the tab stayed open; scripts iterating room ids without respecting membership.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/1983e43e4c034fa0. Report an issue: GitHub.