RocketChat/Rocket.Chat · error · Meteor.Error

not_authorized

not_authorized

Error message

Unauthorized

What it means

clearIntegrationHistory authorizes via one of two permissions: manage-outgoing-integrations (any integration) or manage-own-outgoing-integrations (integrations the caller created). When the user holds neither, this Meteor.Error (not_authorized) is thrown before any lookup happens.

Source

Thrown at apps/meteor/server/lib/integrations/functions/clearIntegrationHistory.ts:20

import { Integrations, IntegrationHistory } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { hasPermissionAsync } from '../../authorization/hasPermission';
import notifications from '../../notifications/core/lib/Notifications';
import { triggerHandler } from '../lib/triggerHandler';

export const clearIntegrationHistoryMethod = async (userId: string, integrationId: string): Promise<void> => {
	let integration: IIntegration | null = null;

	if (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {
		integration = await Integrations.findOneById<IIntegration>(integrationId);
	} else if (await hasPermissionAsync(userId, 'manage-own-outgoing-integrations')) {
		integration = await Integrations.findOne<IIntegration>({
			'_id': integrationId,
			'_createdBy._id': userId,
		});
	} else {
		throw new Meteor.Error('not_authorized', 'Unauthorized', { method: 'clearIntegrationHistory' });
	}

	if (!integration) {
		throw new Meteor.Error('error-invalid-integration', 'Invalid integration', { method: 'clearIntegrationHistory' });
	}

	await IntegrationHistory.removeByIntegrationId(integrationId);

	notifications.streamIntegrationHistory.emit(integrationId, { type: 'removed', id: integrationId });
};

export const replayOutgoingIntegrationMethod = async (
	userId: string,
	{ integrationId, historyId }: { integrationId: string; historyId: string },
): Promise<void> => {
	let integration: IOutgoingIntegration | null = null;

	if (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant manage-outgoing-integrations (full) or manage-own-outgoing-integrations (own only) to the user's role in Administration > Permissions
  2. Or have a user already holding the permission perform the action
Defensive patterns

Strategy: validation

Validate before calling

const canManageAll = await hasPermissionAsync(userId, 'manage-outgoing-integrations');
const canManageOwn = await hasPermissionAsync(userId, 'manage-own-outgoing-integrations');
if (!canManageAll && !canManageOwn) {
  // hide the clear-history action entirely
}

Prevention

When it happens

Trigger: Invoking the clearIntegrationHistory method with a user whose roles lack both outgoing-integration permissions.

Common situations: Custom roles built without integration permissions; permission sets tightened during a security audit; new admins not granted the integration 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/ae834433fc30ed06. Report an issue: GitHub.