RocketChat/Rocket.Chat · error · Meteor.Error

error-not-allowed

error-not-allowed

Error message

Not allowed

What it means

First guard in the cleanRoomHistory execution path: hasPermissionAsync(userId, 'clean-channel-history', roomId) returned false. Cleaning/pruning room history requires the clean-channel-history permission, evaluated against the target room - by default an admin/moderator-level grant.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/cleanRoomHistory.ts:45

}

export const cleanRoomHistoryMethod = async (
	userId: string,
	{
		roomId,
		latest,
		oldest,
		inclusive = true,
		limit,
		excludePinned = false,
		ignoreDiscussion = true,
		filesOnly = false,
		fromUsers = [],
		ignoreThreads,
	}: CleanRoomHistoryParams,
): Promise<number> => {
	if (!(await hasPermissionAsync(userId, 'clean-channel-history', roomId))) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'cleanRoomHistory' });
	}

	const room = await findRoomByIdOrName({ params: { roomId } });

	if (!room || !(await canAccessRoomAsync(room, { _id: userId }))) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'cleanRoomHistory' });
	}

	return cleanRoomHistory({
		rid: roomId,
		latest,
		oldest,
		inclusive,
		limit,
		excludePinned,
		ignoreDiscussion,
		filesOnly,
		fromUsers,

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant clean-channel-history to the acting user's role (Administration > Permissions).
  2. Run the prune as an admin or a role that holds the permission.
  3. Pre-check the permission client-side and hide the prune/clean action when absent.

Example fix

// before
Meteor.call('cleanRoomHistory', roomId, latest, oldest);

// after
if (hasPermission(Meteor.userId(), 'clean-channel-history', roomId)) {
  Meteor.call('cleanRoomHistory', roomId, latest, oldest);
} else {
  showToast('Cleaning history requires the clean-channel-history permission');
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!hasPermission(Meteor.userId(), 'clean-channel-history', roomId)) {
  // do not offer or attempt history cleaning for this room
}

Try / catch

try {
  const removed = await Meteor.callAsync('cleanRoomHistory', roomId, latest, oldest);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-not-allowed') {
    // caller lacks clean-channel-history - surface an admin-actionable message
    showToast('Cleaning history requires the clean-channel-history permission');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: A user without clean-channel-history invokes the cleanRoomHistory method (or the prune-history UI); the permission exists globally but is not granted at the target room scope; role changes removed it after the UI was rendered.

Common situations: Moderators expected to prune but whose role lacks clean-channel-history; retention automations running under a normal user account; fresh workspaces where the permission was never assigned to custom roles.

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/02382e262460d9ee. Report an issue: GitHub.