{"record":{"id":"ff4883811a27577a","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-ff4883","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/platform/setRoomKeyID.ts","lineNumber":19,"sourceCode":"import type { IRoom } from '@rocket.chat/core-typings';\nimport type { ServerMethods } from '@rocket.chat/ddp-client';\nimport { Rooms } from '@rocket.chat/models';\nimport { check } from 'meteor/check';\nimport { Meteor } from 'meteor/meteor';\n\nimport { canAccessRoomIdAsync } from '../../lib/authorization/canAccessRoom';\nimport { notifyOnRoomChanged } from '../../lib/notifyListener';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\t'e2e.setRoomKeyID'(rid: IRoom['_id'], keyID: string): void;\n\t}\n}\n\nexport const setRoomKeyIDMethod = async (userId: string, rid: IRoom['_id'], keyID: string): Promise<void> => {\n\tif (!(await canAccessRoomIdAsync(rid, userId))) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'e2e.setRoomKeyID' });\n\t}\n\n\tconst room = await Rooms.setE2eKeyId(rid, keyID);\n\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-room-e2e-key-already-exists', 'E2E Key ID already exists', {\n\t\t\tmethod: 'e2e.setRoomKeyID',\n\t\t});\n\t}\n\n\tvoid notifyOnRoomChanged(room);\n};\n\nMeteor.methods<ServerMethods>({\n\tasync 'e2e.setRoomKeyID'(rid, keyID) {\n\t\tcheck(rid, String);\n\t\tcheck(keyID, String);\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/platform/setRoomKeyID.ts#L1-L37","documentation":"`setRoomKeyIDMethod` throws `error-invalid-room` when `canAccessRoomIdAsync(rid, userId)` returns false: the rid matches no room, or the user cannot access it (not a member of a private room, no access to that room type). Setting a room's E2E key id requires the caller to already have access to the room.","triggerScenarios":"`Meteor.call('e2e.setRoomKeyID', rid, keyID)` with a typo'd or deleted rid, or a private room the caller never joined (access check fails even though the room exists).","commonSituations":"Client state desync — rid taken from a stale cache; room deleted between load and key submission; guest/bot accounts without membership attempting key exchange.","solutions":["Verify the rid exists and the caller has a subscription to it before invoking","For private rooms, join/be added first so the access check passes","Refresh room data on the client before running E2E key operations"],"exampleFix":"// before\nMeteor.call('e2e.setRoomKeyID', rid, keyID);\n// after\nconst sub = Subscriptions.findOne({ rid });\nif (!sub) {\n  throw new Error('no access to room');\n}\nMeteor.call('e2e.setRoomKeyID', rid, keyID);","handlingStrategy":"validation","validationCode":"const sub = Subscriptions.findOne({ rid });\nif (!sub) {\n  throw new Error('user cannot access room');\n}\nMeteor.call('e2e.setRoomKeyID', rid, keyID);","typeGuard":"const canSubmitRoomKey = (rid: string | undefined, sub: ISubscription | undefined): rid is string =>\n  typeof rid === 'string' && rid.length > 0 && !!sub;","tryCatchPattern":"try {\n  await Meteor.callAsync('e2e.setRoomKeyID', rid, keyID);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-room') {\n    // rid wrong or no access: refresh room data, verify membership, do not blind-retry\n  }\n}","preventionTips":["Confirm a subscription exists for the room before E2E key operations","Reload the room from the server instead of trusting cached rids","For private rooms, ensure membership before starting key exchange"],"tags":["e2ee","authorization","rooms","meteor-method"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}