RocketChat/Rocket.Chat · error · Meteor.Error

error-action-not-allowed

error-action-not-allowed

Error message

Accessing permissions is not allowed

What it means

The core addUserToRole() helper first demands the 'access-permissions' permission from its caller; lacking it throws error-action-not-allowed with action 'Accessing_permissions'. All role-assignment paths (DDP 'authorization:addUserToRole' and the REST roles.addUserToRole flow) funnel through this check, so it applies even if the caller can render the permissions screen.

Source

Thrown at apps/meteor/server/meteor-methods/auth/addUserToRole.ts:12

import { api } from '@rocket.chat/core-services';
import type { IRole, IUser } from '@rocket.chat/core-typings';
import { Roles, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { hasPermissionAsync } from '../../lib/authorization/hasPermission';
import { addUserRolesAsync } from '../../lib/roles/addUserRoles';
import { settings } from '../../settings';

export const addUserToRole = async (userId: string, roleId: string, username: IUser['username'], scope?: string): Promise<boolean> => {
	if (!(await hasPermissionAsync(userId, 'access-permissions'))) {
		throw new Meteor.Error('error-action-not-allowed', 'Accessing permissions is not allowed', {
			method: 'authorization:addUserToRole',
			action: 'Accessing_permissions',
		});
	}

	if (!roleId || typeof roleId.valueOf() !== 'string' || !username || typeof username.valueOf() !== 'string') {
		throw new Meteor.Error('error-invalid-arguments', 'Invalid arguments', {
			method: 'authorization:addUserToRole',
		});
	}

	const role = await Roles.findOneById<Pick<IRole, '_id'>>(roleId, { projection: { _id: 1 } });

	if (!role) {
		throw new Meteor.Error('error-invalid-role', 'Invalid Role', {
			method: 'authorization:addUserToRole',
		});
	}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant 'access-permissions' to the caller's role under Authorization > Permissions.
  2. Perform the assignment as a full admin user.
  3. Switch the automation to an admin token.

Example fix

// before: caller lacks access-permissions -> error-action-not-allowed
Meteor.call('authorization:addUserToRole', roleId, username, scope);

// after: perform as admin (or grant access-permissions to the caller's role first)
await withAdminSession(() => Meteor.callAsync('authorization:addUserToRole', roleId, username, scope));
Defensive patterns

Strategy: try-catch

Validate before calling

// Server-side pre-check mirroring the guard
if (!(await hasPermissionAsync(userId, 'access-permissions'))) {
  throw new Error('caller needs access-permissions');
}
await addUserToRole(userId, roleId, username, scope);

Try / catch

try {
  await addUserToRole(userId, roleId, username, scope);
} catch (err: any) {
  if (err?.error === 'error-action-not-allowed' && err?.details?.action === 'Accessing_permissions') {
    // retry with an admin session or inform the user they lack permission management rights
    return escalateToAdmin(() => addUserToRole(adminId, roleId, username, scope));
  }
  throw err;
}

Prevention

When it happens

Trigger: A user whose roles lack access-permissions calling Meteor.call('authorization:addUserToRole', roleId, username, scope) or the roles.addUserToRole flow; custom permission sets that removed this grant from a staff role.

Common situations: Delegating user management to moderator/sub-admin roles without granting access-permissions; permission-matrix customizations that accidentally dropped the grant; automation using a non-privileged token.

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