RocketChat/Rocket.Chat · error · Error
team-does-not-exist
Error message
team-does-not-exist
What it means
Thrown by TeamService.addMembers (apps/meteor/server/services/team/service.ts:713) when Team.findOneById(teamId, { projection: { roomId: 1 } }) returns null — no team with that ID. The roomId projection is needed because members are added by joining the team's main channel via addUserToRoom. Over REST, teams.addMembers resolves the team first and returns its own 'team-does-not-exist' failure, so seeing the service's throw means a direct call or a delete race.
Source
Thrown at apps/meteor/server/services/team/service.ts:713
}
return {
total: await totalCount,
records: results,
};
}
async addMembers(uid: string, teamId: string, members: Array<ITeamMemberParams>): Promise<void> {
const createdBy = (await Users.findOneById(uid, { projection: { username: 1 } })) as Pick<IUser, '_id' | 'username'>;
if (!createdBy) {
throw new Error('invalid-user');
}
const team = await Team.findOneById<Pick<ITeam, 'roomId'>>(teamId, {
projection: { roomId: 1 },
});
if (!team) {
throw new Error('team-does-not-exist');
}
for await (const member of members) {
const user = (await Users.findOneById(member.userId, { projection: { username: 1 } })) as Pick<IUser, '_id' | 'username'>;
await addUserToRoom(team.roomId, user, createdBy, { skipSystemMessage: false });
if (member.roles) {
const isRoleAddedToTeam = await this.addRolesToMember(teamId, member.userId, member.roles);
const isRoleAddedToSubscription = await this.addRolesToSubscription(team.roomId, member.userId, member.roles);
if (settings.get<boolean>('UI_DisplayRoles') && isRoleAddedToTeam && isRoleAddedToSubscription) {
member.roles.forEach((role) => {
void api.broadcast('user.roleUpdate', {
type: 'added',
_id: role,
u: {
_id: user._id,
username: user.username,
},View on GitHub (pinned to b2c16d5842)
Solutions
- Re-resolve the team immediately before adding members and abort on null
- In long-running sync jobs, catch this error per-team and log/skip rather than aborting the whole run
- Over REST, rely on the endpoint's team-does-not-exist response and refresh the team list in the client
Example fix
// before
await Team.addMembers(uid, staleTeamId, members); // throws team-does-not-exist
// after
const team = await Team.findOneById(teamId, { projection: { roomId: 1 } });
if (!team) {
throw new Error('team-does-not-exist');
}
await Team.addMembers(uid, team._id, members); Defensive patterns
Strategy: try-catch
Validate before calling
const team = await Team.findOneById(teamId, { projection: { roomId: 1 } });
if (!team) {
throw new Error('team-does-not-exist');
}
await Team.addMembers(uid, team._id, members); Try / catch
try {
await Team.addMembers(uid, teamId, members);
} catch (e) {
if (e instanceof Error && e.message === 'team-does-not-exist') {
// team removed mid-sync — skip this batch entry
}
throw e;
} Prevention
- In member-sync jobs, resolve the team per iteration and tolerate deletion
- Refresh team references in UIs after team-management operations
- Log teamId alongside the error to spot environment-mismatched IDs quickly
When it happens
Trigger: Direct Team.addMembers(uid, staleTeamId, members); team deleted between the endpoint's getTeamByIdOrName resolution and the service lookup; mistyped IDs; teams on another workspace.
Common situations: Bulk member-sync jobs running while teams are being reorganized; UI holding a stale team reference after deletion; captured request replay against a different database.
Related errors
- error-team-not-found
- error-team-not-found
- invalid-list-of-rooms
- invalid-calendar-event
- Param ${params.teams.key} must be an array
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/47f9c1e009eb0e4c.
Report an issue: GitHub.