{"record":{"id":"a507c984be965c72","repo":"RocketChat/Rocket.Chat","slug":"not-allowed-a507c9","errorCode":null,"errorMessage":"not-allowed","messagePattern":"not-allowed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/visitors.ts","lineNumber":176,"sourceCode":");\n\nAPI.v1.addRoute(\n\t'livechat/:rid/messages',\n\t{ authRequired: true, permissionsRequired: ['view-l-room'], validateParams: isLivechatRidMessagesProps },\n\t{\n\t\tasync get() {\n\t\t\tconst { offset, count } = await getPaginationItems(this.queryParams);\n\t\t\tconst { sort } = await this.parseJsonQuery();\n\t\t\tconst { searchTerm } = this.queryParams;\n\n\t\t\tconst room = await LivechatRooms.findOneById(this.urlParams.rid);\n\n\t\t\tif (!room) {\n\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\n\t\t\tif (!(await canAccessRoomAsync(room, this.user))) {\n\t\t\t\tthrow new Error('not-allowed');\n\t\t\t}\n\n\t\t\tconst { cursor, totalCount } = Messages.findLivechatClosedMessages(this.urlParams.rid, searchTerm, {\n\t\t\t\tsort: sort || { ts: -1 },\n\t\t\t\tskip: offset,\n\t\t\t\tlimit: count,\n\t\t\t});\n\n\t\t\tconst [messages, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\t\t\treturn API.v1.success({\n\t\t\t\tmessages: await normalizeMessagesForUser(messages, this.userId),\n\t\t\t\toffset,\n\t\t\t\tcount,\n\t\t\t\ttotal,\n\t\t\t});\n\t\t},\n\t},","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/visitors.ts#L158-L194","documentation":"Thrown by GET livechat/:rid/messages when the room exists but canAccessRoomAsync(room, this.user) returns false. So the caller is authenticated and holds view-l-room, but does not have access to this specific room (not a member, not an agent/manager with omnichannel scope, etc.).","triggerScenarios":"An agent without omnichannel-manager scope querying a room they are not assigned to; a user who has view-l-room globally but is filtered out by room-level access checks; a monitor without the right department routing.","commonSituations":"Over-broad permission granted to a role but tighter per-room/department restrictions still apply; cross-department data access attempt in a multi-department setup.","solutions":["Grant the user membership or omnichannel-manager scope on the target room/department.","Use an account with view-livechat-rooms or omnichannel-manager privileges for cross-room inspection.","Confirm department routing includes the caller's scope."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"const canAccess = await fetch(`/api/v1/v1/rooms.canAccess?rid=${rid}`, { headers }).then(r => r.json());\nif (!canAccess.canAccess) throw new Error('insufficient scope');","typeGuard":"null","tryCatchPattern":"try { await fetch(url); } catch (e) { if (e.error === 'not-allowed') { /* escalate to omnichannel-manager account or request access */ } }","preventionTips":["Use an omnichannel-manager scoped account for cross-room inspection.","Confirm department routing includes the caller before fetching.","Do not assume view-l-room alone grants per-room access."],"tags":["omnichannel","messages","permissions","room-access"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}