{"record":{"id":"04053118f9116721","repo":"RocketChat/Rocket.Chat","slug":"room-closed-040531","errorCode":"room-closed","errorMessage":"Room is closed","messagePattern":"Room is closed","errorType":"error_code","errorClass":"MeteorError","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/services/room/service.ts","lineNumber":190,"sourceCode":"\t\tsendMessage = true,\n\t): Promise<void> {\n\t\tawait saveRoomTopic(roomId, roomTopic, user, sendMessage);\n\t}\n\n\tasync getRouteLink(room: AtLeast<IRoom, '_id' | 't' | 'name'>): Promise<string | boolean> {\n\t\treturn roomCoordinator.getRouteLink(room.t as string, { rid: room._id, name: room.name });\n\t}\n\n\t/**\n\t * Method called by users to join a room.\n\t */\n\tasync join({ room, user, joinCode }: { room: IRoom; user: IUser; joinCode?: string }) {\n\t\tif (!(await roomCoordinator.getRoomDirectives(room.t)?.allowMemberAction(room, RoomMemberActions.JOIN, user._id))) {\n\t\t\tthrow new MeteorError('error-not-allowed', 'Not allowed', { method: 'joinRoom' });\n\t\t}\n\n\t\tif (isOmnichannelRoom(room) && !room.open) {\n\t\t\tthrow new MeteorError('room-closed', 'Room is closed', { method: 'joinRoom' });\n\t\t}\n\n\t\tif (!(await Authorization.canAccessRoom(room, user))) {\n\t\t\tthrow new MeteorError('error-not-allowed', 'Not allowed', { method: 'joinRoom' });\n\t\t}\n\n\t\tif (\n\t\t\tFederationActions.shouldPerformFederationAction(room) &&\n\t\t\t!isUserNativeFederated(user) &&\n\t\t\t!(await FederationMatrix.canUserAccessFederation(user))\n\t\t) {\n\t\t\tthrow new MeteorError('error-not-authorized-federation', 'Not authorized to access federation', { method: 'joinRoom' });\n\t\t}\n\n\t\tif (isRoomWithJoinCode(room) && !(await Authorization.hasPermission(user._id, 'join-without-join-code'))) {\n\t\t\tif (!joinCode) {\n\t\t\t\tthrow new MeteorError('error-code-required', 'Code required', { method: 'joinRoom' });\n\t\t\t}","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/services/room/service.ts#L172-L208","documentation":"During join(), omnichannel rooms that are not open (room.open !== true, i.e. the conversation is closed) are rejected with Meteor error room-closed ('Room is closed', method 'joinRoom'). Closed omnichannel conversations cannot be re-joined as members; they must be reopened through the omnichannel flow.","triggerScenarios":"Calling join on an omnichannel room whose conversation is already closed — the visitor ended it, an agent closed it, or routing/timeout closed it.","commonSituations":"Agents trying to rejoin closed conversations directly via the join API; clients holding stale room references after the conversation closed.","solutions":["Re-open the conversation through the omnichannel UI/API (e.g. take/claim the inquiry) instead of calling join","Filter out closed rooms before attempting a join","On error, refresh the room state in the client and stop offering join for closed conversations"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { isOmnichannelRoom } from '@rocket.chat/core-typings';\n\nif (isOmnichannelRoom(room) && !room.open) {\n  // closed conversation: reopen via omnichannel flow, never join()\n  return reopenConversation(room._id);\n}","typeGuard":"const isJoinableOmnichannelRoom = (room: IRoom): boolean =>\n  !isOmnichannelRoom(room) || room.open === true;","tryCatchPattern":"try {\n  await roomService.join({ room, user });\n} catch (err) {\n  if (err?.error === 'room-closed') {\n    // refresh state and offer to reopen the conversation; join() will keep failing while closed\n    return refreshRoomAndPromptReopen(room._id);\n  }\n  throw err;\n}","preventionTips":["Filter closed rooms out of joinable lists in the UI","Handle conversation-closed events so stale room references are dropped","Reopen closed omnichannel conversations through the omnichannel API, not join()"],"tags":["omnichannel","rooms","join","room-closed","rocket-chat"],"backgroundTag":"conversation-already-closed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}