RocketChat/Rocket.Chat · error · Meteor.Error
not_authorized
not_authorized
Error message
Unauthorized
What it means
Thrown by the deleteIncomingIntegration helper when the caller holds neither 'manage-incoming-integrations' nor 'manage-own-incoming-integrations' (or userId is empty, since both checks are gated on !!userId). Either permission alone is sufficient; the error means the caller has neither at the time of the call.
Source
Thrown at apps/meteor/server/meteor-methods/integrations/incoming/deleteIncomingIntegration.ts:22
import { hasPermissionAsync } from '../../../lib/authorization/hasPermission';
import { methodDeprecationLogger } from '../../../lib/deprecationWarningLogger';
import { notifyOnIntegrationChanged } from '../../../lib/notifyListener';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
deleteIncomingIntegration(integrationId: string): Promise<boolean>;
}
}
export const deleteIncomingIntegration = async (integrationId: string, userId: string): Promise<void> => {
const canManageAllIntegrations = !!userId && (await hasPermissionAsync(userId, 'manage-incoming-integrations'));
const canManageOwnIntegrations =
!canManageAllIntegrations && !!userId && (await hasPermissionAsync(userId, 'manage-own-incoming-integrations'));
if (!canManageAllIntegrations && !canManageOwnIntegrations) {
throw new Meteor.Error('not_authorized', 'Unauthorized', {
method: 'deleteIncomingIntegration',
});
}
const integration = await Integrations.removeByIdAndCreatedByIfExists({
_id: integrationId,
...(canManageOwnIntegrations && { createdBy: userId }),
});
if (!integration) {
throw new Meteor.Error('error-invalid-integration', 'Invalid integration', {
method: 'deleteIncomingIntegration',
});
}
void notifyOnIntegrationChanged(integration, 'removed');
};
View on GitHub (pinned to b2c16d5842)
Solutions
- Grant 'manage-incoming-integrations' (full) or 'manage-own-incoming-integrations' (own only) to a role the caller holds
- Have the caller log out and back in so refreshed permissions reach the client, then retry
- Or delete the integration from an admin account; for automation use DELETE /api/v1/integrations.remove
Example fix
// before
await Meteor.callAsync('deleteIncomingIntegration', id); // by a user with no integration permission
// after: perform the delete as an admin-managed service
await fetch(`${root}/api/v1/integrations.remove`, { method: 'POST', headers: { 'X-Auth-Token': adminToken, 'X-User-Id': adminUid }, body: JSON.stringify({ integrationId: id, type: 'webhook-incoming' }) }); Defensive patterns
Strategy: try-catch
Try / catch
try {
await Meteor.callAsync('deleteIncomingIntegration', integrationId);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'not_authorized') { /* hide delete affordance; suggest admin or permission grant */ }
} Prevention
- Show delete buttons only for users with an integration-management permission
- Re-login after role changes
- Route automated cleanup through an authorized REST token
When it happens
Trigger: A regular user without any integration permission calls deleteIncomingIntegration; permissions were revoked but the client session still caches old role state; userId passed as empty string when invoking the exported helper.
Common situations: Admin removed integration rights as cleanup and users' open admin screens kept the delete button enabled; permission changes requiring re-login to take effect in the client's cached role subscription.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- error-user-lacks-message-impersonate-permission
- not_authorized
- error-invalid-channel
- error-invalid-channel-start-with-chars
- error-invalid-username
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/7b785ec9b73906b3.
Report an issue: GitHub.