{"record":{"id":"9c98bffee26e02b9","repo":"RocketChat/Rocket.Chat","slug":"cannot-access-room","errorCode":"cannot-access-room","errorMessage":"cannot-access-room","messagePattern":"cannot-access-room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/omnichannel/rooms.ts","lineNumber":80,"sourceCode":"\n\tif (room?.v._id && (await LivechatContacts.isChannelBlocked(Visitors.makeVisitorAssociation(room.v._id, room.source)))) {\n\t\tthrow new Error('error-contact-channel-blocked');\n\t}\n\n\tif (!room?.open) {\n\t\tlivechatLogger.debug({ msg: 'Last room for visitor closed. Creating new one', visitorId: guest._id });\n\t}\n\n\tif (!room?.open) {\n\t\treturn {\n\t\t\troom: await createRoom({ visitor: guest, message: message.msg, roomInfo, agent, extraData }),\n\t\t\tnewRoom: true,\n\t\t};\n\t}\n\n\tif (room.v.token !== guest.token) {\n\t\tlivechatLogger.debug({ msg: 'Visitor trying to access another visitor room', visitorId: guest._id });\n\t\tthrow new Meteor.Error('cannot-access-room');\n\t}\n\n\treturn { room, newRoom: false };\n}\n\nexport async function createRoom({\n\tvisitor,\n\tmessage,\n\trid,\n\troomInfo,\n\tagent,\n\textraData,\n}: {\n\tvisitor: ILivechatVisitor;\n\tmessage?: string;\n\trid?: string;\n\troomInfo: IOmnichannelRoomInfo;\n\tagent?: SelectedAgent;","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/omnichannel/rooms.ts#L62-L98","documentation":"When the found room is open, getRoom compares room.v.token with guest.token. A mismatch means the caller is trying to use a room that belongs to a different visitor, so Meteor.Error('cannot-access-room') is thrown instead of returning the room.","triggerScenarios":"Calling the livechat flow with a rid whose room belongs to another visitor token: an rid copied from another session, a token that was regenerated (visitor record recreated / cookies cleared) while a stale rid is reused, or two widget instances sharing state.","commonSituations":"Persisted rid in localStorage surviving a visitor re-initialization; test scripts reusing rid/token pairs; multi-tab widgets leaking token/rid state.","solutions":["Always obtain a room via the visitor's own token instead of reusing a stored rid.","Clear the stored rid and token together whenever the visitor session resets.","In REST integrations, fetch rid from the same visitor context that owns the token (livechat visitor/room creation endpoints)."],"exampleFix":"// before\n// reusing rid from another session -> cannot-access-room\nconst { room } = await getRoom(guest, { rid: storedRid, msg, token }, roomInfo);\n\n// after\n// drop the stale rid; let the flow find/create the room for this token\nconst { room, newRoom } = await getRoom(guest, { rid: makeRid(guest.token), msg, token: guest.token }, roomInfo);","handlingStrategy":"validation","validationCode":"const room = await LivechatRooms.findOneById(message.rid, { projection: { 'v.token': 1, open: 1 } });\nif (room?.open && room.v?.token !== guest.token) {\n\tthrow new Error('rid belongs to a different visitor - request a new room');\n}","typeGuard":"const isRoomOwnedByGuest = (room: { v?: { token?: string } } | null, guest: { token?: string }): boolean =>\n\tBoolean(room?.v?.token && room.v.token === guest.token);","tryCatchPattern":"try {\n\tconst { room } = await getRoom(guest, message, roomInfo);\n} catch (err) {\n\tif (err instanceof Meteor.Error && err.error === 'cannot-access-room') {\n\t\t// drop the stored rid and create a fresh room for this token\n\t\treturn;\n\t}\n\tthrow err;\n}","preventionTips":["Never persist rid beyond the visitor session that produced it.","Reset rid and token together when the visitor is re-initialized.","Derive rooms from the visitor's own token via the official livechat endpoints."],"tags":["omnichannel","livechat","visitor-token","authorization","rooms"],"backgroundTag":"token-mismatch","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}