{"record":{"id":"b7c01751a36684bd","repo":"RocketChat/Rocket.Chat","slug":"error-no-permission","errorCode":"error-no-permission","errorMessage":"No permission","messagePattern":"No permission","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/publications/room/index.ts","lineNumber":88,"sourceCode":"\t\t}\n\n\t\tconst roomFind = roomCoordinator.getRoomFind(type);\n\n\t\tconst room = roomFind ? await roomFind.call(this, name) : await Rooms.findByTypeAndNameOrId(type, name);\n\n\t\tif (!room) {\n\t\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\t\tmethod: 'getRoomByTypeAndName',\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\tuser &&\n\t\t\t!(await canAccessRoomAsync(room, user, {\n\t\t\t\tincludeInvitations: true,\n\t\t\t}))\n\t\t) {\n\t\t\tthrow new Meteor.Error('error-no-permission', 'No permission', {\n\t\t\t\tmethod: 'getRoomByTypeAndName',\n\t\t\t});\n\t\t}\n\n\t\tif (settings.get('Store_Last_Message') && user && !(await hasPermissionAsync(user, 'preview-c-room'))) {\n\t\t\tdelete room.lastMessage;\n\t\t}\n\n\t\treturn roomMap(room);\n\t},\n});\n","sourceCodeStart":70,"sourceCodeEnd":100,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/publications/room/index.ts#L70-L100","documentation":"Thrown by 'getRoomByTypeAndName' when the authenticated user fails canAccessRoomAsync(room, user, { includeInvitations: true }) — the user is neither a member, nor invited, nor otherwise allowed to see the room. This is the authorization check that runs after the room was found and after the anonymous checks passed.","triggerScenarios":"A logged-in user who never joined a private channel ('p') calls getRoomByTypeAndName('p', 'private-room'); a user removed from a team channel retries the lookup; direct-message room access by a third party.","commonSituations":"Deep links to private rooms shared with non-members; clients that prefetch room metadata for URLs pasted in chat; permission changes (membership revoked) not yet reflected client-side.","solutions":["Join the room first (or ask an admin for an invitation/membership)","Pre-check access with canAccessRoomAsync before calling the method","Handle error-no-permission gracefully (hide content, offer a join flow)"],"exampleFix":"// before\nconst room = await Meteor.callAsync('getRoomByTypeAndName', 'p', name);\n\n// after (server-side pre-check)\nconst room = await Rooms.findByTypeAndNameOrId('p', name);\nif (!(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {\n  throw new Meteor.Error('error-no-permission');\n}","handlingStrategy":"validation","validationCode":"const room = await Rooms.findByTypeAndNameOrId(type, name);\nif (!room || !(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {\n  throw new Error('user cannot access this room');\n}\nMeteor.call('getRoomByTypeAndName', type, name);","typeGuard":"async function userCanAccessRoom(user: Meteor.User, room: IRoom): Promise<boolean> {\n  return canAccessRoomAsync(room, user, { includeInvitations: true });\n}","tryCatchPattern":"try { await Meteor.callAsync('getRoomByTypeAndName', type, name); } catch (e) { if (e.error === 'error-no-permission') { /* offer join/leave flow, do not retry */ } }","preventionTips":["Check membership (subscriptions) before fetching private room metadata","Refresh access state after membership or permission changes"],"tags":["meteor","rooms","authorization","permissions","rocket-chat"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}