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
- Grant 'access-permissions' to the caller's role under Authorization > Permissions.
- Perform the assignment as a full admin user.
- 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 delegating user management, grant access-permissions to the delegated role explicitly.
- Audit custom permission sets after role/permission refactors.
- Use admin tokens for provisioning scripts.
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.