RocketChat/Rocket.Chat · error · Meteor.Error

error-no-permission

error-no-permission

Error message

No permission

What it means

Thrown by 'getRoomByTypeAndName' when the authenticated user fails canAccessRoomAsync(room, user, { includeInvitations: true }) — the user is neither a member, nor invited, nor otherwise allowed to see the room. This is the authorization check that runs after the room was found and after the anonymous checks passed.

Source

Thrown at apps/meteor/server/publications/room/index.ts:88

		}

		const roomFind = roomCoordinator.getRoomFind(type);

		const room = roomFind ? await roomFind.call(this, name) : await Rooms.findByTypeAndNameOrId(type, name);

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

		if (
			user &&
			!(await canAccessRoomAsync(room, user, {
				includeInvitations: true,
			}))
		) {
			throw new Meteor.Error('error-no-permission', 'No permission', {
				method: 'getRoomByTypeAndName',
			});
		}

		if (settings.get('Store_Last_Message') && user && !(await hasPermissionAsync(user, 'preview-c-room'))) {
			delete room.lastMessage;
		}

		return roomMap(room);
	},
});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Join the room first (or ask an admin for an invitation/membership)
  2. Pre-check access with canAccessRoomAsync before calling the method
  3. Handle error-no-permission gracefully (hide content, offer a join flow)

Example fix

// before
const room = await Meteor.callAsync('getRoomByTypeAndName', 'p', name);

// after (server-side pre-check)
const room = await Rooms.findByTypeAndNameOrId('p', name);
if (!(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {
  throw new Meteor.Error('error-no-permission');
}
Defensive patterns

Strategy: validation

Validate before calling

const room = await Rooms.findByTypeAndNameOrId(type, name);
if (!room || !(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {
  throw new Error('user cannot access this room');
}
Meteor.call('getRoomByTypeAndName', type, name);

Type guard

async function userCanAccessRoom(user: Meteor.User, room: IRoom): Promise<boolean> {
  return canAccessRoomAsync(room, user, { includeInvitations: true });
}

Try / catch

try { await Meteor.callAsync('getRoomByTypeAndName', type, name); } catch (e) { if (e.error === 'error-no-permission') { /* offer join/leave flow, do not retry */ } }

Prevention

When it happens

Trigger: A logged-in user who never joined a private channel ('p') calls getRoomByTypeAndName('p', 'private-room'); a user removed from a team channel retries the lookup; direct-message room access by a third party.

Common situations: Deep links to private rooms shared with non-members; clients that prefetch room metadata for URLs pasted in chat; permission changes (membership revoked) not yet reflected client-side.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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