RocketChat/Rocket.Chat · error · Meteor.Error
not_authorized
not_authorized
Error message
Unauthorized
What it means
addIncomingIntegration rejects with not_authorized when there is no userId OR the user holds neither `manage-incoming-integrations` nor `manage-own-incoming-integrations`. Creating incoming webhooks requires at least one of these two permissions; the check runs after the integration object passes its Match validation.
Source
Thrown at apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts:48
enabled: Boolean,
username: String,
channel: String,
alias: Match.Maybe(String),
emoji: Match.Maybe(String),
scriptEnabled: Boolean,
scriptEngine: Match.Maybe(String),
overrideDestinationChannelEnabled: Match.Maybe(Boolean),
script: Match.Maybe(String),
avatar: Match.Maybe(String),
}),
);
if (
!userId ||
(!(await hasPermissionAsync(userId, 'manage-incoming-integrations')) &&
!(await hasPermissionAsync(userId, 'manage-own-incoming-integrations')))
) {
throw new Meteor.Error('not_authorized', 'Unauthorized', {
method: 'addIncomingIntegration',
});
}
if (!integration.channel || typeof integration.channel.valueOf() !== 'string') {
throw new Meteor.Error('error-invalid-channel', 'Invalid channel', {
method: 'addIncomingIntegration',
});
}
if (integration.channel.trim() === '') {
throw new Meteor.Error('error-invalid-channel', 'Invalid channel', {
method: 'addIncomingIntegration',
});
}
const channels = integration.channel.split(',').map((channel) => channel.trim());
View on GitHub (pinned to b2c16d5842)
Solutions
- Grant `manage-incoming-integrations` (full control) or `manage-own-incoming-integrations` (own webhooks only) to the caller's role
- Verify authentication first — the same error covers a missing userId
- For REST use POST /v1/integrations.create with a token whose role carries one of these permissions
Example fix
// before
Meteor.call('addIncomingIntegration', integration, cb); // not_authorized
// after
const canManage = usePermission('manage-incoming-integrations') || usePermission('manage-own-incoming-integrations');
if (canManage) Meteor.call('addIncomingIntegration', integration, cb); Defensive patterns
Strategy: validation
Validate before calling
const canManage =
usePermission('manage-incoming-integrations') || usePermission('manage-own-incoming-integrations');
if (Meteor.userId() && canManage) {
Meteor.call('addIncomingIntegration', integration, cb);
} Try / catch
Meteor.call('addIncomingIntegration', integration, (err) => {
if (err && (err as Meteor.Error).error === 'not_authorized') {
// either not logged in or missing BOTH manage-incoming-integrations and
// manage-own-incoming-integrations — check session first, then permissions
}
}); Prevention
- Grant manage-own-incoming-integrations to roles that may create their own webhooks
- Check both the session and one of the two permissions before showing the create form
- For REST, give the token's role one of these permissions before calling /v1/integrations.create
When it happens
Trigger: Calling `Meteor.call('addIncomingIntegration', integration)` while logged out, or as a user whose roles include neither integration permission — e.g. a regular member or a bot account without the integration role.
Common situations: Allowing non-admins to create their own webhooks without granting manage-own-incoming-integrations; custom roles built by copying 'user' instead of a privileged template; scripts assuming admin rights on a restricted token.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- error-invalid-role
- error-permission-not-found
- error-action-not-allowed
- error-action-not-allowed
- not_authorized
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/89e4d6123d5213c3.
Report an issue: GitHub.