RocketChat/Rocket.Chat · error · Meteor.Error
error-action-not-allowed
error-action-not-allowed
Error message
Editing settings is not allowed
What it means
saveSettingsBulk collects ids the caller may not edit and, if any exist, fails the whole save with 'error-action-not-allowed'. Two gates push ids into settingsNotAllowed: (1) the caller lacks edit-privileged-setting AND does not have manage-selected-settings plus the per-setting permission (getSettingPermissionId(_id)); (2) on deployments where custom scripts are disabled (cloud trials), any Custom_Script_* setting is blocked to prevent phishing injections. The rejected ids come back in the error details as settingIds.
Source
Thrown at apps/meteor/server/settings/lib/saveSettingsBulk.ts:110
break;
case 'multiSelect':
check(value, Array);
break;
case 'code':
check(value, String);
if (isSettingCode(setting) && setting.code === 'application/json') {
check(value, validJSON);
}
break;
default:
check(value, String);
break;
}
}),
);
if (settingsNotAllowed.length) {
throw new Meteor.Error('error-action-not-allowed', 'Editing settings is not allowed', {
method: 'saveSettings',
settingIds: settingsNotAllowed,
});
}
validateSettingRules(params);
const auditSettingOperation = updateAuditedByUser({
_id: uid,
username: audit.username,
ip: audit.ip,
useragent: audit.useragent,
});
const promises = params.map(async ({ _id, value, editor }) => {
const valueResult = await auditSettingOperation(Settings.updateValueById, _id, value);
if (!editor) {View on GitHub (pinned to b2c16d5842)
Solutions
- Run the save with a user that has edit-privileged-setting (or manage-selected-settings plus the specific setting's permission)
- Remove Custom_Script_* ids from the payload on workspaces that block custom scripts
- Read error.details.settingIds to see exactly which ids were rejected and split them out of the bulk update
- Have an admin perform privileged settings changes through the admin UI instead
Example fix
// before
await POST('/api/v1/settings', [{ _id: 'Custom_Script_Logged_Out', value: '<script>...' }]);
// -> error-action-not-allowed, settingIds: ['Custom_Script_Logged_Out']
// after - authenticate with edit-privileged-setting and drop blocked ids
const allowed = params.filter(({ _id }) => !blockedIds.includes(_id));
await POST('/api/v1/settings', allowed); Defensive patterns
Strategy: validation
Validate before calling
const canEditPrivileged = await hasPermissionAsync(uid, 'edit-privileged-setting');
const canManageSelected = await hasPermissionAsync(uid, 'manage-selected-settings');
if (!canEditPrivileged && !canManageSelected) {
throw new Meteor.Error('forbidden', 'Use an account with edit-privileged-setting');
}
const safeParams = params.filter(({ _id }) => !disableCustomScripts() || !/^Custom_Script_/.test(_id));
await saveSettingsBulk(uid, safeParams, audit); Try / catch
catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-action-not-allowed') {
const blocked = err.details?.settingIds ?? [];
// remove blocked ids, escalate to a privileged user, or use the admin UI
} else throw err;
} Prevention
- Use a privileged account (edit-privileged-setting) for settings automation
- Never include Custom_Script_* ids in payloads on cloud workspaces
- Split bulk saves so blocked settings fail alone, not the whole batch
When it happens
Trigger: A non-admin or a role without edit-privileged-setting saving privileged settings via the API; any attempt to update Custom_Script_* settings on a cloud workspace where custom scripts are disabled; automation using a low-privilege user token for settings writes.
Common situations: Scripts with regular user tokens hitting saveSettings; cloud or enterprise trials hardening script settings; permission drift after role changes removed edit-privileged-setting from an admin 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
- error-action-not-allowed
- error-action-not-allowed
- error-not-allowed
- error-action-not-allowed
- error-not-authorized
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/c64477a48e0a1be3.
Report an issue: GitHub.