RocketChat/Rocket.Chat · error · Meteor.Error
error-duplicate-channel-name
error-duplicate-channel-name
Error message
A channel with name '${cleanName}' exists What it means
Same special-chars path as its archived sibling, but the conflicting room (same display name, different _id) is live, so creation/rename is refused with error-duplicate-channel-name. Contrast the lower branch of the same function: in the non-special-chars path Rocket.Chat auto-appends -2, -3… suffixes instead of throwing — throwing on duplicates only happens for display-name matches when UI_Allow_room_names_with_special_chars is on.
Source
Thrown at apps/meteor/server/lib/utils/lib/getValidRoomName.ts:23
import { settings } from '../../../settings';
import { validateName } from '../../shared/validateName';
export const getValidRoomName = async (displayName: string, rid = '', options: { allowDuplicates?: boolean } = {}) => {
let slugifiedName = displayName;
if (settings.get('UI_Allow_room_names_with_special_chars')) {
const cleanName = limax(displayName, { maintainCase: true });
if (options.allowDuplicates !== true) {
const room = await Rooms.findOneByDisplayName(displayName);
if (room && room._id !== rid) {
if (room.archived) {
throw new Meteor.Error('error-archived-duplicate-name', `There's an archived channel with name ${cleanName}`, {
function: 'RocketChat.getValidRoomName',
channel_name: cleanName,
});
} else {
throw new Meteor.Error('error-duplicate-channel-name', `A channel with name '${cleanName}' exists`, {
function: 'RocketChat.getValidRoomName',
channel_name: cleanName,
});
}
}
}
slugifiedName = cleanName;
}
let nameValidation;
try {
nameValidation = new RegExp(`^${settings.get('UTF8_Channel_Names_Validation')}$`);
} catch (error) {
nameValidation = new RegExp('^[0-9a-zA-Z-_.]+$');
}
if (!nameValidation.test(slugifiedName) || !validateName(slugifiedName)) {View on GitHub (pinned to b2c16d5842)
Solutions
- Choose a different display name
- Pass { allowDuplicates: true } when the caller's semantics allow same display names (slugs still differ)
- Rename or delete the existing live channel first if consolidation is intended
Example fix
// before
await getValidRoomName('general'); // live channel named 'general' exists
// after
await getValidRoomName('general', '', { allowDuplicates: true });
// or pick a distinct name
await getValidRoomName('general-eng'); Defensive patterns
Strategy: validation
Validate before calling
import { Rooms } from '@rocket.chat/models';
const existing = await Rooms.findOneByDisplayName(displayName);
if (existing && existing._id !== rid && !existing.archived) {
// name taken by a live room: block or suggest alternatives
} Try / catch
try {
await getValidRoomName(name, rid);
} catch (error) {
if (error instanceof Meteor.Error && error.error === 'error-duplicate-channel-name') {
// suggest name variants (name-2, name-team)
} else {
throw error;
}
} Prevention
- Pre-check display-name availability while the user types the channel name
- Consider allowDuplicates: true for workspaces that key rooms by slug, not display name
- Distinguish archived vs live duplicates in UI messaging — the remedies differ
When it happens
Trigger: Creating or renaming a channel to the display name of an active channel (UI_Allow_room_names_with_special_chars on, allowDuplicates !== true).
Common situations: Common channel names ('general', 'random', 'announcements'); parallel departments naming channels identically; imports colliding with existing rooms.
Related errors
- error-archived-duplicate-name
- error-invalid-room-name
- duplicated-account
- error-field-unavailable
- error-invalid-room
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/e7dbb0dace373bcf.
Report an issue: GitHub.