{"record":{"id":"9524ac32a8becec4","repo":"RocketChat/Rocket.Chat","slug":"error-user-lacks-message-impersonate-permission","errorCode":"error-user-lacks-message-impersonate-permission","errorMessage":"User selected for the incoming integration lacks the 'message-impersonate' permission.","messagePattern":"User selected for the incoming integration lacks the 'message-impersonate' permission\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts","lineNumber":94,"sourceCode":"\t\tthrow new Meteor.Error('error-invalid-username', 'Invalid username', {\n\t\t\tmethod: 'addIncomingIntegration',\n\t\t});\n\t}\n\n\tif (integration.script?.trim()) {\n\t\tvalidateScriptEngine(integration.scriptEngine ?? 'isolated-vm');\n\t}\n\n\tconst user = await Users.findOneByUsername(integration.username, { projection: { _id: 1 } });\n\n\tif (!user) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\tmethod: 'addIncomingIntegration',\n\t\t});\n\t}\n\n\tif (!(await hasPermissionAsync(user._id, 'message-impersonate'))) {\n\t\tthrow new Meteor.Error(\n\t\t\t'error-user-lacks-message-impersonate-permission',\n\t\t\t\"User selected for the incoming integration lacks the 'message-impersonate' permission.\",\n\t\t\t{\n\t\t\t\tmethod: 'addIncomingIntegration',\n\t\t\t},\n\t\t);\n\t}\n\n\t// Default to transpiling with Babel for backwards compatibility; integrations\n\t// can opt-out per-record by setting `skipTranspile: true` (removed in 9.0.0).\n\tconst skipTranspile = integration.skipTranspile === true;\n\n\tconst integrationData: IIncomingIntegration = {\n\t\t...integration,\n\t\tscriptEngine: integration.scriptEngine ?? 'isolated-vm',\n\t\tskipTranspile,\n\t\ttype: 'webhook-incoming',\n\t\tchannel: channels,","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts#L76-L112","documentation":"Thrown by addIncomingIntegration when the 'post as' user resolves but does not hold the 'message-impersonate' permission. The server checks hasPermissionAsync(user._id, 'message-impersonate') on the TARGET user (the one the webhook posts as), not on the caller. This is a security requirement: an incoming webhook sends messages under this user's identity, so impersonation rights are mandatory.","triggerScenarios":"Choosing a regular employee as the post-as user; creating a bot account whose role lacks message-impersonate; an admin removed message-impersonate from the default bot role as hardening and existing creation flows broke.","commonSituations":"Fresh workspace where the custom bot role was cloned from User (which lacks the permission); compliance-driven permission lockdowns; integrations built against older Rocket.Chat that did not enforce this check.","solutions":["Grant 'message-impersonate' to a role held by the target user: Administration -> Permissions -> message-impersonate, tick the bot/custom role","Or pick a post-as user that already has the permission (e.g. the built-in rocket.cat or a user with admin/bot role that includes it)","As admin you can also run: Meteor.call('authorization:addPermissionToRole', 'message-impersonate', 'bot') then retry"],"exampleFix":"// before: target user's role lacks the permission\nMeteor.callAsync('addIncomingIntegration', { ...integration, username: 'intern.user' }); // -> error-user-lacks-message-impersonate-permission\n// after: grant the permission to the user's role (Administration -> Permissions -> message-impersonate -> check 'bot'), then\nMeteor.callAsync('addIncomingIntegration', { ...integration, username: 'ci-bot' }); // ci-bot has role 'bot' with message-impersonate","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await Meteor.callAsync('addIncomingIntegration', integration);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-user-lacks-message-impersonate-permission') {\n    // show 'ask an admin to grant message-impersonate to this user's role' and keep form state\n  }\n}","preventionTips":["Provision bot roles with message-impersonate included from day one","Restrict the post-as picker to users whose roles carry message-impersonate","Document the permission in your integration onboarding runbook"],"tags":["rocket-chat","incoming-integration","permissions","impersonation","meteor-method"],"backgroundTag":"insufficient-permissions","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}