RocketChat/Rocket.Chat · error · MeteorError

error-invalid-contact-manager

error-invalid-contact-manager

Error message

The contact manager must have the role "livechat-agent"

What it means

registerContact found a user with the given contactManager.username, but that user's roles array is missing, malformed, or does not include 'livechat-agent'. Omnichannel requires contact managers to be livechat agents so routing and visibility rules hold. This is a role/permission problem, not a lookup problem — the user exists but is not an agent.

Source

Thrown at apps/meteor/server/lib/omnichannel/contacts/registerContact.ts:41

export async function registerContact(
	{ token, name, email = '', phone, username, customFields = {}, contactManager }: RegisterContactProps,
	userId: string,
): Promise<string> {
	if (!token || typeof token !== 'string') {
		throw new MeteorError('error-invalid-contact-data', 'Invalid visitor token');
	}

	const visitorEmail = email.trim().toLowerCase();

	if (contactManager?.username) {
		// verify if the user exists with this username and has a livechat-agent role
		const manager = await Users.findOneByUsername(contactManager.username, { projection: { roles: 1 } });
		if (!manager) {
			throw new MeteorError('error-contact-manager-not-found', `No user found with username ${contactManager.username}`);
		}
		if (!manager.roles || !Array.isArray(manager.roles) || !manager.roles.includes('livechat-agent')) {
			throw new MeteorError('error-invalid-contact-manager', 'The contact manager must have the role "livechat-agent"');
		}
	}

	const existingUserByToken = await LivechatVisitors.getVisitorByToken(token, { projection: { _id: 1 } });
	let visitorId = existingUserByToken?._id;

	if (!existingUserByToken) {
		if (!username) {
			username = await LivechatVisitors.getNextVisitorUsername();
		}

		const existingUserByEmail = await LivechatVisitors.findOneGuestByEmailAddress(visitorEmail);
		visitorId = existingUserByEmail?._id;

		if (!existingUserByEmail) {
			const userData = {
				username,
				ts: new Date(),

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Add the 'livechat-agent' role to the user (POST /api/v1/user.update or add them under Administration > Omnichannel > Agents)
  2. Confirm the user now appears as an agent via GET /api/v1/livechat/agents, then retry registration
  3. If the user should not be an agent, pass a different contactManager.username or omit contactManager

Example fix

// before
// user 'johndoe' exists but has roles: ['user']
await registerContact({ token, email, contactManager: { username: 'johndoe' } }, userId);

// after
await POST('/api/v1/user.update', { userId, data: { roles: ['user', 'livechat-agent'] } });
await registerContact({ token, email, contactManager: { username: 'johndoe' } }, userId);
Defensive patterns

Strategy: type-guard

Validate before calling

const manager = await Users.findOneByUsername(contactManager.username, { projection: { roles: 1 } });
if (!manager?.roles?.includes('livechat-agent')) {
  throw new Error('Contact manager must be a livechat agent; add the role first');
}
await registerContact(params, userId);

Type guard

type AgentUser = { _id: string; roles?: string[] };
const isLivechatAgent = (u: AgentUser | null): u is AgentUser & { roles: string[] } =>
  Array.isArray(u?.roles) && (u.roles as string[]).includes('livechat-agent');

Try / catch

try {
  await registerContact(params, userId);
} catch (err) {
  if (err instanceof MeteorError && err.code === 'error-invalid-contact-manager') {
    // add livechat-agent role or pick another manager, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: POST /api/v1/omnichannel/contact (or registerContact) with contactManager.username of a valid user who was never added as an omnichannel agent, was removed from the agent list, or whose roles field is empty/non-array due to a data issue.

Common situations: Admin removed the agent from Omnichannel > Agents but integrations still reference them; user was created via SSO without the livechat-agent role; roles document corrupted after a migration.

Related errors


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