RocketChat/Rocket.Chat · error · MeteorError

error-contact-manager-not-found

error-contact-manager-not-found

Error message

No user found with username ${contactManager.username}

What it means

Thrown by registerContact (reached via POST /api/v1/omnichannel/contact) when the request body includes a contactManager.username but no Users document matches that username. The registration validates the manager up-front, before creating or linking the visitor/contact, because a contact manager must reference a real user. The interpolated message echoes the exact username that failed the lookup.

Source

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

		username: string;
	};
};

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) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the exact username with GET /api/v1/users.info?username=... (usernames are case-sensitive) and correct the payload
  2. Confirm the user still exists and is not deleted or merged into another account
  3. If no manager is intended, omit the contactManager object entirely from the request instead of sending an empty/placeholder username
  4. If syncing from an external directory, re-sync so the username mapping matches Rocket.Chat

Example fix

// before
await registerContact({ token, email, contactManager: { username: 'john.doe' } }, userId); // 'john.doe' does not exist

// after
const manager = await Users.findOneByUsername('johndoe', { projection: { _id: 1 } });
if (!manager) throw new MeteorError('error-contact-manager-not-found', 'Unknown manager');
await registerContact({ token, email, contactManager: { username: 'johndoe' } }, userId);
Defensive patterns

Strategy: validation

Validate before calling

const manager = await Users.findOneByUsername(contactManager.username, { projection: { _id: 1, username: 1 } });
if (!manager) {
  throw new Error(`Unknown contact manager username: ${contactManager.username}`);
}
await registerContact({ ...params, contactManager: { username: manager.username } }, userId);

Type guard

const isContactManagerRef = (v: unknown): v is { username: string } =>
  typeof v === 'object' && v !== null && typeof (v as { username?: unknown }).username === 'string' && (v as { username: string }).username.length > 0;

Try / catch

try {
  await registerContact(params, userId);
} catch (err) {
  if (err instanceof MeteorError && err.code === 'error-contact-manager-not-found') {
    // surface 'manager username does not exist' to the caller; do not retry with same payload
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the omnichannel contact register endpoint (or registerContact directly) with contactManager.username set to a value that has no matching Users record: typo, wrong case, deleted/merged user, or a username sourced from LDAP/SCIM sync that diverges from Rocket.Chat's username.

Common situations: Client stores email or display name where the API expects the Rocket.Chat username; the agent account was renamed or deactivated after the client cached it; external sync provisioned users under different usernames than expected.

Related errors


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