RocketChat/Rocket.Chat · error · Meteor.Error

error-user-is-not-agent

error-user-is-not-agent

Error message

error-user-is-not-agent

What it means

A 'beforeJoinRoom' callback (registered in omnichannel startup) rejects joining omnichannel rooms unless the user has the 'view-l-room' permission; otherwise it throws Meteor.Error('error-user-is-not-agent', 'User is not an Omnichannel Agent', { method: 'beforeJoinRoom' }). The permission is normally granted via the livechat-agent role, so in practice it means 'this user is not an omnichannel agent'.

Source

Thrown at apps/meteor/server/lib/omnichannel/startup.ts:91

		(user, room) => {
			if (!isOmnichannelRoom(room)) {
				return;
			}
			throw new Meteor.Error(
				i18n.t('You_cant_leave_a_livechat_room_Please_use_the_close_button', {
					lng: user.language || settings.get('Language') || 'en',
				}),
			);
		},
		callbacks.priority.LOW,
		'cant-leave-omnichannel-room',
	);

	callbacks.add(
		'beforeJoinRoom',
		async (user, room) => {
			if (isOmnichannelRoom(room) && !(await hasPermissionAsync(user, 'view-l-room'))) {
				throw new Meteor.Error('error-user-is-not-agent', 'User is not an Omnichannel Agent', {
					method: 'beforeJoinRoom',
				});
			}

			return user;
		},
		callbacks.priority.LOW,
		'cant-join-omnichannel-room',
	);

	const monitor = new LivechatAgentActivityMonitor();

	settings.watch<boolean>('Troubleshoot_Disable_Livechat_Activity_Monitor', async (value) => {
		if (value) {
			return monitor.stop();
		}

		await monitor.start();

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Add the user as an Omnichannel agent (Administration > Omnichannel > Agents) — this grants the livechat-agent role and view-l-room
  2. Or grant 'view-l-room' to the user's role manually in Administration > Permissions if they must join without being a routed agent
  3. Verify with a permissions check before joining (see validation below)
  4. Reload the user's session/roles after permission changes

Example fix

// before
await Meteor.callAsync('joinRoom', rid); // throws error-user-is-not-agent

// after
const canJoin = await hasPermissionAsync(Meteor.user(), 'view-l-room');
if (isOmnichannelRoom(room) && !canJoin) {
  throw new Meteor.Error('error-user-is-not-agent');
}
await Meteor.callAsync('joinRoom', rid);
Defensive patterns

Strategy: validation

Validate before calling

import { hasPermissionAsync } from '../../authorization/hasPermission';

if (isOmnichannelRoom(room) && !(await hasPermissionAsync(user, 'view-l-room'))) {
  throw new Meteor.Error('error-user-is-not-agent', 'Grant view-l-room or add as omnichannel agent');
}
await Meteor.callAsync('joinRoom', rid);

Type guard

function isOmnichannelRoom(v: { t?: string } | null | undefined): v is { _id: string; t: 'l' } {
  return v?.t === 'l';
}

Try / catch

try {
  await Meteor.callAsync('joinRoom', rid);
} catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-user-is-not-agent') {
    // user is not an agent: add them via Omnichannel > Agents, then retry
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling joinRoom (Meteor method) for a room with t: 'l' as a user without view-l-room permission — typically a non-agent user, an agent whose role lost the permission, or a bot/app user not registered as an omnichannel agent.

Common situations: Admin adds a user to a livechat room without making them an agent, custom roles missing view-l-room after a permission reset, apps-engine bots trying to join omnichannel rooms, or users removed from the omnichannel agents list but still in old UI sessions.

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/2a394b3fb1209598. Report an issue: GitHub.