{"record":{"id":"f2ac555491b8b6b9","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-f2ac55","errorCode":"error-not-allowed","errorMessage":"Bot request not allowed","messagePattern":"Bot request not allowed","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/bot-helpers/index.ts","lineNumber":106,"sourceCode":"\t\t});\n\t}\n\n\tasync removeUserFromRoom(userName: string, room: string) {\n\t\tconst foundRoom = await Rooms.findOneByIdOrName(room);\n\n\t\tif (!foundRoom) {\n\t\t\tthrow new Meteor.Error('invalid-channel');\n\t\t}\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user');\n\t\t}\n\t\tawait removeUserFromRoomMethod(userId, { rid: foundRoom._id, username: userName });\n\t}\n\n\t// generic error whenever property access insufficient to fill request\n\trequestError() {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Bot request not allowed', {\n\t\t\tmethod: 'botRequest',\n\t\t\taction: 'bot_request',\n\t\t});\n\t}\n\n\t// \"public\" properties accessed by getters\n\t// allUsers / onlineUsers return whichever properties are enabled by settings\n\tget allUsers() {\n\t\tif (!Object.keys(this.userFields).length) {\n\t\t\tthis.requestError();\n\t\t\treturn false;\n\t\t}\n\t\treturn this._allUsers.toArray();\n\t}\n\n\tget onlineUsers() {\n\t\tif (!Object.keys(this.userFields).length) {\n\t\t\tthis.requestError();","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/bot-helpers/index.ts#L88-L124","documentation":"requestError() is the BotHelpers generic guard: every getter that depends on admin-configured data calls it when the configuration does not expose enough information to answer the request. The whitelist is the BotHelpers_userFields setting (watched at module load, fed into setupCursors); 'allUsers'/'onlineUsers' throw when it is empty, 'allUsernames'/'onlineUsernames' when it lacks 'username', 'allNames'/'onlineNames' when it lacks 'name', and 'allIDs'/'onlineIDs' when it lacks '_id' or 'username'.","triggerScenarios":"botRequest('allUsers') or 'onlineUsers' on a server where BotHelpers_userFields is empty; botRequest('allUsernames') when the setting list omits 'username'; botRequest('allNames') when it omits 'name'; 'allIDs'/'onlineIDs' when it omits '_id' or 'username'.","commonSituations":"Fresh installs where the admin never configured bot helper fields; settings cleared during migration; admins intentionally locking down bot data access while bot apps still request those properties.","solutions":["Set the BotHelpers_userFields setting (comma-separated field list) to include every field the bot requests, e.g. 'username,name,_id' for the IDs getters.","Retry the request after the setting propagates (the settings.watch re-runs setupCursors).","If the data must stay private, stop requesting that property in the bot and handle error-not-allowed gracefully instead."],"exampleFix":"// BotHelpers_userFields setting\n// before\n''\n\n// after\n'username,name,_id,status'","handlingStrategy":"try-catch","validationCode":"import { settings } from '../../settings';\n\n// server-side pre-check before granting bots the property\nconst fields = String(settings.get('BotHelpers_userFields') ?? '').split(',').map((f) => f.trim());\nconst required = { allUsers: [], onlineUsers: [], allUsernames: ['username'], allIDs: ['_id', 'username'], allNames: ['name'] };\nif (required[prop].some((f) => !fields.includes(f))) {\n  throw new Error(`BotHelpers_userFields must include: ${required[prop].join(', ') || 'at least one field'}`);\n}","typeGuard":"const botPropAllowed = (prop: string, fieldsSetting: string): boolean => {\n  const fields = fieldsSetting.split(',').map((f) => f.trim());\n  if (prop === 'allUsers' || prop === 'onlineUsers') return fields.length > 0;\n  if (prop === 'allUsernames' || prop === 'onlineUsernames') return fields.includes('username');\n  if (prop === 'allNames' || prop === 'onlineNames') return fields.includes('name');\n  if (prop === 'allIDs' || prop === 'onlineIDs') return fields.includes('_id') && fields.includes('username');\n  return true;\n};","tryCatchPattern":"try {\n  const users = await Meteor.callAsync('botRequest', 'allUsers');\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-not-allowed') {\n    // configuration issue: ask the admin to fill BotHelpers_userFields, or degrade gracefully\n  }\n  throw e;\n}","preventionTips":["Configure BotHelpers_userFields to include every field the bot's requests touch before shipping the bot.","Treat error-not-allowed from botRequest as a configuration signal, not a transient failure — never auto-retry it.","Document, per bot feature, which user fields it needs so admins can whitelist them in one pass."],"tags":["rocket-chat","bot","settings","not-allowed"],"backgroundTag":"feature-disabled-by-config","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}