RocketChat/Rocket.Chat · error · Error
team-name-already-exists
Error message
team-name-already-exists
What it means
TeamService.create() validates the team name with checkUsernameAvailability(team.name, 'room'), which returns false when the name is already taken (case-insensitively) by any user's username, any existing team, or — via the availability callback for type 'room' — a room. A false result is reported as team-name-already-exists. (Blocked/invalid names like 'all' or 'here' throw error-blocked-username earlier in that helper.)
Source
Thrown at apps/meteor/server/services/team/service.ts:44
import { Team, Rooms, Subscriptions, Users, TeamMember } from '@rocket.chat/models';
import { escapeRegExp } from '@rocket.chat/tools';
import type { Document, FindOptions, Filter } from 'mongodb';
import { notifyOnSubscriptionChangedByRoomIdAndUserId, notifyOnRoomChangedById } from '../../lib/notifyListener';
import { addUserToRoom } from '../../lib/rooms/addUserToRoom';
import { getSubscribedRoomsForUserWithDetails } from '../../lib/rooms/getRoomsWithSingleOwner';
import { removeUserFromRoom } from '../../lib/rooms/removeUserFromRoom';
import { saveRoomName } from '../../lib/rooms/settings';
import { saveRoomType } from '../../lib/rooms/settings/saveRoomType';
import { checkUsernameAvailability } from '../../lib/users/checkUsernameAvailability';
import { settings } from '../../settings';
export class TeamService extends ServiceClassInternal implements ITeamService {
protected name = 'team';
async create(uid: string, { team, room = { name: team.name, extraData: {} }, members, owner }: ITeamCreateParams): Promise<ITeam> {
if (!(await checkUsernameAvailability(team.name, 'room'))) {
throw new Error('team-name-already-exists');
}
const existingRoom = await Rooms.findOneByName(team.name, { projection: { _id: 1 } });
if (existingRoom && existingRoom._id !== room.id) {
throw new Error('room-name-already-exists');
}
const createdBy = await Users.findOneById<Pick<IUser, 'username' | '_id'>>(uid, {
projection: { username: 1 },
});
if (!createdBy) {
throw new Error('invalid-user');
}
// TODO add validations to `data` and `members`
const membersResult =
!members || !Array.isArray(members) || members.length === 0View on GitHub (pinned to b2c16d5842)
Solutions
- Choose a different team name
- Pre-check with checkUsernameAvailability(name, 'room') before submitting the create form
- If the collision is with a leftover room/team from a failed create, remove it and retry
Example fix
// before
await teamService.create(uid, { team: { name: 'support' }, /* ... */ });
// after
if (!(await checkUsernameAvailability('support', 'room'))) {
throw new Error('team-name-already-exists'); // surface in the form before calling the service
}
await teamService.create(uid, { team: { name: 'support' }, /* ... */ }); Defensive patterns
Strategy: validation
Validate before calling
import { checkUsernameAvailability } from '/app/lib/users/checkUsernameAvailability';
if (!(await checkUsernameAvailability(team.name, 'room'))) {
// name is taken by a user, team, or room (case-insensitive): pick another before create()
return markNameUnavailable(team.name);
} Type guard
const isTeamNameAvailable = async (name: string): Promise<boolean> => checkUsernameAvailability(name, 'room');
Try / catch
try {
await teamService.create(uid, params);
} catch (err) {
if (err instanceof Error && err.message === 'team-name-already-exists') {
// surface inline in the form; auto-suggest an available variant instead of retrying
return suggestNameVariants(params.team.name);
}
throw err;
} Prevention
- Teams share the username namespace: check names against users, teams, and rooms before submitting
- Debounce an availability check on the create-team form
- Clean up partially created teams/rooms after failed creates so names do not stay taken
When it happens
Trigger: Creating a team whose name equals an existing user's username, an existing team's name, or an existing room's name, in any casing — teams share the username namespace.
Common situations: Name collisions with users; retries after partial failures where the name got taken in between; reserved/blacklisted names handled separately.
Related errors
- room-name-already-exists
- Param ${params.teams.key} must be an array
- error-team-not-found
- error-not-allowed
- error-team-not-found
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/dc5aff45c0cd4c41.
Report an issue: GitHub.