RocketChat/Rocket.Chat · error · Meteor.Error
error-user-lacks-message-impersonate-permission
error-user-lacks-message-impersonate-permission
Error message
User selected for the incoming integration lacks the 'message-impersonate' permission.
What it means
Thrown by updateIncomingIntegration when the user configured as the integration's 'Post As' account lacks the 'message-impersonate' permission. The server resolves integration.username (falling back to the stored integration's username) via Users.findOneByUsername, then checks hasPermissionAsync(user._id, 'message-impersonate') before persisting the update. Incoming integrations post canal messages impersonating that user, so the explicit permission gate applies to the impersonated account, not the caller.
Source
Thrown at apps/meteor/server/meteor-methods/integrations/incoming/updateIncomingIntegration.ts:155
!(await Subscriptions.findOneByRoomIdAndUserId(record._id, userId, { projection: { _id: 1 } }))
) {
throw new Meteor.Error('error-invalid-channel', 'Invalid Channel', {
method: 'updateIncomingIntegration',
});
}
}
const username = 'username' in integration ? integration.username : currentIntegration.username;
const user = await Users.findOneByUsername(username, { projection: { _id: 1, username: 1 } });
if (!user) {
throw new Meteor.Error('error-invalid-post-as-user', 'Invalid Post As User', {
method: 'updateIncomingIntegration',
});
}
if (!(await hasPermissionAsync(user._id, 'message-impersonate'))) {
throw new Meteor.Error(
'error-user-lacks-message-impersonate-permission',
"User selected for the incoming integration lacks the 'message-impersonate' permission.",
{
method: 'updateIncomingIntegration',
},
);
}
const updatedIntegration = await Integrations.findOneAndUpdate(
{ _id: integrationId },
{
$set: {
enabled: integration.enabled,
name: integration.name,
...(typeof integration.avatar !== 'undefined' && { avatar: integration.avatar }),
...(typeof integration.emoji !== 'undefined' && { emoji: integration.emoji }),
...(typeof integration.alias !== 'undefined' && { alias: integration.alias }),
...(channels && { channel: channels }),View on GitHub (pinned to b2c16d5842)
Solutions
- Grant 'message-impersonate' to the target user's role (Administration > Permissions, e.g. add it to the bot role), then retry the update
- Or set integration.username to an account that already has the permission, typically the integration's own bot user
- If the payload omits username, remember the stored username is re-checked — fix that integration's Post As user or grant the permission and submit again
- For automation, use the equivalent REST endpoint POST /v1/integrations.update with an auth token
Example fix
// before
await Meteor.callAsync('updateIncomingIntegration', integrationId, {
...integration,
username: 'alice', // alice's role lacks message-impersonate
});
// after: impersonate a bot user whose role has message-impersonate
await Meteor.callAsync('updateIncomingIntegration', integrationId, {
...integration,
username: 'my-integration-bot',
}); Defensive patterns
Strategy: validation
Validate before calling
// server-side, before updating an incoming integration
import { hasPermissionAsync } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/core-server';
const postAsUsername = payload.username ?? existingIntegration.username;
const user = await Users.findOneByUsername(postAsUsername, { projection: { _id: 1 } });
if (!user || !(await hasPermissionAsync(user._id, 'message-impersonate'))) {
// pick another Post As user or grant the permission first
throw new Error(`Post As user '${postAsUsername}' cannot be impersonated`);
} Try / catch
try {
await Meteor.callAsync('updateIncomingIntegration', id, payload);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-user-lacks-message-impersonate-permission') {
// surface: grant message-impersonate to the Post As user or choose a bot account
return;
}
throw err;
} Prevention
- Keep a dedicated bot user per integration whose role includes message-impersonate
- When building Post As pickers, filter the user list to accounts holding message-impersonate
- After role or permission changes, re-validate existing integrations' Post As users
When it happens
Trigger: Meteor call to updateIncomingIntegration(integrationId, integration) where integration.username — or the previously stored username when the payload omits it — names a user whose roles do not include 'message-impersonate'; also fires when an admin revokes that permission from the bot role after the integration was created.
Common situations: Selecting a regular (non-bot) user as Post As, since by default only bot-like roles carry message-impersonate; migrating integrations between workspaces with different role definitions; role/permission audits that strip message-impersonate from the bot role.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/b968dbae972cd60e.
Report an issue: GitHub.