{"record":{"id":"1ff960f1fbf5d1f7","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-1ff960","errorCode":null,"errorMessage":"error-not-allowed","messagePattern":"error-not-allowed","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/lib/messages.ts","lineNumber":23,"sourceCode":"import { canAccessRoomAsync } from '../../lib/authorization/canAccessRoom';\n\nexport async function findMentionedMessages({\n\tuid,\n\troomId,\n\tpagination: { offset, count, sort },\n}: {\n\tuid: string;\n\troomId: string;\n\tpagination: { offset: number; count: number; sort: FindOptions<IMessage>['sort'] };\n}): Promise<{\n\tmessages: IMessage[];\n\tcount: number;\n\toffset: number;\n\ttotal: number;\n}> {\n\tconst room = await Rooms.findOneById(roomId);\n\tif (!room || !(await canAccessRoomAsync(room, { _id: uid }))) {\n\t\tthrow new Error('error-not-allowed');\n\t}\n\tconst user = await Users.findOneById<Pick<IUser, 'username'>>(uid, { projection: { username: 1 } });\n\tif (!user) {\n\t\tthrow new Error('invalid-user');\n\t}\n\n\tconst { cursor, totalCount } = Messages.findPaginatedVisibleByMentionAndRoomId(user.username, roomId, {\n\t\tsort: sort || { ts: -1 },\n\t\tskip: offset,\n\t\tlimit: count,\n\t});\n\n\tconst [messages, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\treturn {\n\t\tmessages,\n\t\tcount: messages.length,\n\t\toffset,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/lib/messages.ts#L5-L41","documentation":"findMentionedMessages (apps/meteor/server/api/lib/messages.ts) backs GET /api/v1/chat.getMentionedMessages. It first loads the room by roomId and checks canAccessRoomAsync(room, { _id: uid }); if the room does not exist OR the authenticated user cannot access it, it throws plain Error 'error-not-allowed'. Access can fail because the user is not a member of a private channel/team, is banned, or lacks view-history rights on that room type.","triggerScenarios":"GET /api/v1/chat.getMentionedMessages?roomId=<rid> where rid is wrong/deleted, or where the authed user is not in the private channel or team, or the user's subscription is banned.","commonSituations":"Bot token expected to read a private room it was never invited to; roomId copied from another workspace; room archived/deleted between calls; testing with a personal token against a private support channel.","solutions":["Confirm the room exists and grab its canonical _id via GET /api/v1/rooms.info?roomId=...","Have the user (or bot) added to the private channel/team before querying mentions","If banned, the subscription is treated as no access — resolve the ban first","Use an account that already participates in the room for read operations"],"exampleFix":"// before\nGET /api/v1/chat.getMentionedMessages?roomId=GENERAL-but-mistyped\n\n// after\nGET /api/v1/rooms.info?roomName=general               // resolve real _id\nGET /api/v1/chat.getMentionedMessages?roomId=GENERAL   // user is a member here","handlingStrategy":"validation","validationCode":"async function canAccessRoom(client, roomId: string): Promise<boolean> {\n  try {\n    const r = await client.get('/api/v1/rooms.info', { params: { roomId } });\n    return r.ok; // 404/403 when missing or not a member\n  } catch {\n    return false;\n}\n}","typeGuard":null,"tryCatchPattern":"try {\n  const { data } = await client.get('/api/v1/chat.getMentionedMessages', { params: { roomId } });\n} catch (e: any) {\n  if ((e?.response?.data?.error ?? '') === 'error-not-allowed') {\n    throw new ForbiddenError(`no access to room ${roomId}`);\n  }\n  throw e;\n}","preventionTips":["Resolve roomIds from rooms.info/rooms.list rather than persisting them long-term","Invite bots to private rooms before scheduling mention reads","Treat 'error-not-allowed' as terminal for that room — retrying without membership changes nothing"],"tags":["rest-api","chat","room-access","authorization"],"backgroundTag":"room-access-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}