RocketChat/Rocket.Chat · error · Meteor.Error

error-duplicate-handle

error-duplicate-handle

Error message

A room, team or user with name '${slugifiedRoomName}' already exists

What it means

Thrown by updateRoomName inside saveRoomName when checkUsernameAvailability(slugifiedRoomName, 'room') returns false (saveRoomName.ts:27) — the slugified target name collides with an existing room, team, or user handle, since these share one namespace. slugifiedRoomName comes from getValidRoomName(displayName, rid); the error embeds the offending handle in details { handle }. Code 'error-duplicate-handle'.

Source

Thrown at apps/meteor/server/lib/rooms/settings/saveRoomName.ts:27

import { notifyOnIntegrationChangedByChannels, notifyOnSubscriptionChangedByRoomId } from '../../notifyListener';
import { checkUsernameAvailability } from '../../users/checkUsernameAvailability';
import { getValidRoomName } from '../../utils/lib/getValidRoomName';
import { roomCoordinator } from '../roomCoordinator';

const updateFName = async (rid: string, displayName: string): Promise<(UpdateResult | Document)[]> => {
	const responses = await Promise.all([Rooms.setFnameById(rid, displayName), Subscriptions.updateFnameByRoomId(rid, displayName)]);

	if (responses[1]?.modifiedCount) {
		void notifyOnSubscriptionChangedByRoomId(rid);
	}

	return responses;
};

const updateRoomName = async (rid: string, displayName: string, slugifiedRoomName: string) => {
	// Check if the name is available
	if (!(await checkUsernameAvailability(slugifiedRoomName, 'room'))) {
		throw new Meteor.Error('error-duplicate-handle', `A room, team or user with name '${slugifiedRoomName}' already exists`, {
			function: 'RocketChat.updateRoomName',
			handle: slugifiedRoomName,
		});
	}

	const responses = await Promise.all([
		Rooms.setNameById(rid, slugifiedRoomName, displayName),
		Subscriptions.updateNameAndAlertByRoomId(rid, slugifiedRoomName, displayName),
	]);

	if (responses[1]?.modifiedCount) {
		void notifyOnSubscriptionChangedByRoomId(rid);
	}

	return responses;
};

export async function saveRoomName(

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pick a different display name — the message names the exact conflicting handle
  2. Rename or delete the conflicting user/room/team that owns the handle, if that object is the disposable one
  3. Pre-check availability before offering the rename: await checkUsernameAvailability(slugified, 'room')
  4. For programmatic renames, retry with a suffixed name (name-2) since a concurrent creator may have claimed the handle

Example fix

// before
await saveRoomName(rid, 'support', user);

// after
const slug = await getValidRoomName('support', rid);
if (!(await checkUsernameAvailability(slug, 'room'))) {
	throw new Meteor.Error('error-duplicate-handle', `A room, team or user with name '${slug}' already exists`);
}
await saveRoomName(rid, 'support', user);
Defensive patterns

Strategy: validation

Validate before calling

const slugified = await getValidRoomName(displayName, rid);
if (!(await checkUsernameAvailability(slugified, 'room'))) {
	throw new Meteor.Error('error-duplicate-handle', `Name '${slugified}' is taken by a room, team or user`);
}
await saveRoomName(rid, displayName, user);

Try / catch

try {
	await saveRoomName(rid, displayName, user);
} catch (e) {
	if (e instanceof Meteor.Error && e.error === 'error-duplicate-handle') {
		// e.details.handle names the conflict; prompt for another name or auto-suffix
	}
}

Prevention

When it happens

Trigger: Renaming a channel to a name already used by a user/room/team (e.g. 'general', an existing username); two admins renaming to the same free name simultaneously (check-then-set race between checkUsernameAvailability and Rooms.setNameById); a discussion/federation-unrelated path where slugified name equals a reserved handle.

Common situations: Renaming channels into well-known names ('support', 'admin') that exist as usernames; teams and channels competing for the same handle after a reorganization; bulk rename scripts not accounting for the shared namespace.

Related errors


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