{"record":{"id":"ec1055a07f278eb9","repo":"RocketChat/Rocket.Chat","slug":"error-cannot-delete-team-channel","errorCode":"error-cannot-delete-team-channel","errorMessage":"Cannot delete a team channel","messagePattern":"Cannot delete a team channel","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/rooms.ts","lineNumber":208,"sourceCode":"\t\t\t\tadditionalProperties: false,\n\t\t\t}),\n\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tconst { roomId } = this.bodyParams;\n\n\t\tconst room = await Rooms.findOneById(roomId);\n\n\t\tif (!room) {\n\t\t\tthrow new MeteorError('error-invalid-room', 'Invalid room', {\n\t\t\t\tmethod: 'eraseRoom',\n\t\t\t});\n\t\t}\n\n\t\tif (room.teamMain) {\n\t\t\tthrow new Meteor.Error('error-cannot-delete-team-channel', 'Cannot delete a team channel', {\n\t\t\t\tmethod: 'eraseRoom',\n\t\t\t});\n\t\t}\n\n\t\tawait eraseRoom(room, this.user);\n\n\t\treturn API.v1.success();\n\t},\n);\n\nAPI.v1.get(\n\t'rooms.get',\n\t{\n\t\tauthRequired: true,\n\t\tresponse: {\n\t\t\t200: ajv.compile<{ update: IRoom[]; remove: IRoom[] }>({\n\t\t\t\ttype: 'object',\n\t\t\t\tproperties: {","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/rooms.ts#L190-L226","documentation":"Thrown by DELETE/POST rooms.eraseRoom when the target room has its 'teamMain' flag set. Rocket.Chat teams own one primary channel that anchors the team; deleting it would orphan the team, so the server refuses. To remove it you must delete the whole team, not the channel in isolation.","triggerScenarios":"POST /api/v1/rooms.eraseRoom with { roomId } where that room is the main channel of a team (room.teamMain === true). Also reached by any internal caller invoking the eraseRoom action handler after the room is loaded and the teamMain check runs.","commonSituations":"Migration/cleanup scripts that naively iterate all rooms and delete them; converting a team back into ordinary channels; admin tooling that doesn't account for teams; CI that creates a team then tries to tear it down room-by-room.","solutions":["If you want the team gone, delete the team (teams.delete / team removal flow) instead of the single channel.","If you must remove the channel, first convert the team so this room is no longer teamMain (remove the team association), then call eraseRoom.","Pre-check room.teamMain via rooms.info or rooms.get before calling eraseRoom and skip or branch accordingly.","Filter team-main rooms out of any bulk-delete job."],"exampleFix":"// before\nawait rest.post('/api/v1/rooms.eraseRoom', { roomId });\n\n// after\nconst info = await rest.get(`/api/v1/rooms.info?roomId=${roomId}`);\nif (info.room.teamMain) {\n  // delete the owning team instead, or unteam the channel first\n  await rest.post('/api/v1/teams.delete', { teamName: info.room.teamId });\n} else {\n  await rest.post('/api/v1/rooms.eraseRoom', { roomId });\n}","handlingStrategy":"validation","validationCode":"const info = await rest.get(`/api/v1/rooms.info?roomId=${roomId}`);\nif (info.room?.teamMain) {\n  // do NOT call eraseRoom; delete the team instead\n  throw new Error(`Room ${roomId} is a team's main channel; delete via teams.delete`);\n}","typeGuard":"function isTeamMainRoom(r: { teamMain?: boolean } | undefined | null): boolean {\n  return !!r?.teamMain;\n}","tryCatchPattern":"try {\n  await rest.post('/api/v1/rooms.eraseRoom', { roomId });\n} catch (e) {\n  if (isMeteorError(e, 'error-cannot-delete-team-channel')) {\n    // fall back to deleting the owning team\n  } else throw e;\n}","preventionTips":["Pre-filter bulk delete lists by room.teamMain === false.","Surface team-main status in the delete-confirm UI and disable the button.","Document that team channels are deleted only through the teams API."],"tags":["teams","rooms","rest-api","delete-protected"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}