RocketChat/Rocket.Chat · error · Error
room-not-on-team
Error message
room-not-on-team
What it means
Thrown by TeamService.updateRoom (apps/meteor/server/services/team/service.ts:464) when the fetched room document has no teamId field — the channel does not belong to any team. updateRoom only manages team channel properties (teamDefault / auto-join), so a non-team room is a state error rather than a not-found one. The room and user checks have already passed when this throws.
Source
Thrown at apps/meteor/server/services/team/service.ts:464
const room = await Rooms.findOneById(rid);
if (!room) {
throw new Error('invalid-room');
}
const user = await Users.findOneById(uid);
if (!user) {
throw new Error('invalid-user');
}
if (!canUpdateAnyRoom) {
const canSeeRoom = await Authorization.canAccessRoom(room, user);
if (!canSeeRoom) {
throw new Error('invalid-room');
}
}
if (!room.teamId) {
throw new Error('room-not-on-team');
}
room.teamDefault = isDefault;
await Rooms.setTeamDefaultById(rid, isDefault);
if (isDefault) {
const maxNumberOfAutoJoinMembers = settings.get<number>('API_User_Limit');
const teamMembers = await this.members(
uid,
room.teamId,
true,
{ offset: 0, count: maxNumberOfAutoJoinMembers },
// We should not get the owner of the room, since he is already a member
{ _id: { $ne: room.u._id } },
);
for await (const m of teamMembers.records) {
if (await addUserToRoom(room._id, m.user, user)) {
room.usersCount++;View on GitHub (pinned to b2c16d5842)
Solutions
- Confirm the room is still on the team before updating: check room.teamId equals your team's _id
- Re-fetch the team's channel list (GET teams.listRooms) and use a current roomId
- If the room legitimately left the team, drop the update — there is nothing to toggle; treat this error as an idempotency signal in retry logic
Example fix
// before
await Team.updateRoom(uid, rid, true); // throws room-not-on-team after removal
// after
const room = await Rooms.findOneById(rid, { projection: { teamId: 1 } });
if (!room?.teamId) {
return API.v1.failure('room-not-on-team'); // already detached — nothing to update
}
await Team.updateRoom(uid, rid, true); Defensive patterns
Strategy: validation
Validate before calling
const room = await Rooms.findOneById(rid, { projection: { teamId: 1 } });
if (!room?.teamId) {
throw new Error('room-not-on-team'); // nothing to update
}
await Team.updateRoom(uid, rid, isDefault, canUpdateAny); Type guard
const isTeamRoom = (room: IRoom | null): room is IRoom & { teamId: string } =>
!!room && typeof room.teamId === 'string' && room.teamId.length > 0; Try / catch
try {
await Team.updateRoom(uid, rid, isDefault);
} catch (e) {
if (e instanceof Error && e.message === 'room-not-on-team') {
// room already detached — idempotent success or refresh UI
}
throw e;
} Prevention
- Re-fetch the team's channel list before editing after any removeRoom/convert operation
- Treat room-not-on-team as an idempotency signal, not an error, in retry queues
- Check room.teamId matches your expected team _id to catch cross-team staleness
When it happens
Trigger: POST /api/v1/teams.updateRoom for a channel that was already removed from its team (teams.removeRoom) or converted; calling updateRoom on a plain channel/private group that was never part of a team; a race where the room is detached from the team (unsetTeamId) between the endpoint's team lookup and the service call.
Common situations: Stale UI showing a channel under a team after it was removed elsewhere; scripts replaying old room lists; double-processing of the same request after the first already removed the room from the team.
Related errors
- Param ${params.teams.key} must be an array
- error-invalid-room
- room-name-already-exists
- invalid-list-of-rooms
- Only channels, private groups and direct messages can be cre
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/fea14a55face7ae0.
Report an issue: GitHub.