7.1.1 regression: "Sorry, you are not allowed to give users that role." when Multi-Role Support is enabled and default_role is not in get_editable_roles()
Summary
AAM 7.1.1 introduced a regression that causes role assignment to fail with:
Sorry, you are not allowed to give users that role.
This affects single-site WordPress installs where Multi-Role Support is enabled and the site's WordPress default role (set via Settings → General) has been filtered out of get_editable_roles() — for example by a theme or plugin using the editable_roles filter.
The error affects all users including administrators, and occurs on both user-edit.php and user-new.php.
Root Cause (with diff evidence)
The change introduced in 7.1.1 is in application/Backend/tmpl/user/multiple-roles.php:
+ <input type="hidden" value="<?php echo esc_js(get_option('default_role')); ?>" name="role" />
This was intended to satisfy wp_ensure_editable_role() (added in WordPress 6.7), which validates that $_POST['role'] is present and corresponds to a role in get_editable_roles().
The problem: the hidden field is hardcoded to get_option('default_role') — typically subscriber — regardless of which role the user actually selected in AAM's aam_user_roles[] multi-select. If the site has filtered subscriber out of get_editable_roles() (a common pattern for sites that don't use built-in WP roles), wp_ensure_editable_role() sees an invalid role and calls wp_die().
Behaviour comparison
|
AAM 7.1.0 |
AAM 7.1.1 |
$_POST['role'] on user-edit.php |
native WP <select name="role"> (correct role) |
hidden <input name="role"> hardcoded to get_option('default_role') |
$_POST['aam_user_roles[]'] |
present |
present |
wp_ensure_editable_role() result |
✅ passes |
❌ fails if default_role ∉ get_editable_roles() |
Environment
|
|
| WordPress version |
6.9.4 (reproducible on any 6.7+) |
| AAM version |
7.1.1 |
| Setup |
Single-site |
| PHP version |
8.x |
| Multi-Role Support |
Enabled (AAM → Settings → Core Settings) |
| Trigger condition |
Site's default_role is excluded from get_editable_roles() |
Steps to Reproduce
- Install WordPress (single-site) with AAM 7.1.1
- Enable Multiple Roles Support in AAM → Settings → Core Settings
- In your theme or a plugin, add a filter that removes the default role from editable roles:
add_filter('editable_roles', function ($roles) {
unset($roles['subscriber']); // or whatever get_option('default_role') returns
return $roles;
});
- Log in as an Administrator
- Go to
wp-admin/users.php and click Edit on any user
- Change the user's role using AAM's role selector
- Click Update User
Expected Behaviour
The user's role is updated to the role selected in AAM's multi-role field.
Actual Behaviour
Sorry, you are not allowed to give users that role.
wp_ensure_editable_role() validates $_POST['role'] which AAM 7.1.1 set to get_option('default_role') — a role that is not present in get_editable_roles() on this site.
Suggested Fix
Instead of hardcoding get_option('default_role') in the hidden field, use the first role from aam_user_roles[] — the role the user actually selected:
- <input type="hidden" value="<?php echo esc_js(get_option('default_role')); ?>" name="role" />
+ <input type="hidden" value="<?php echo esc_js(!empty($_GET['aam_user_roles'][0]) ? $_GET['aam_user_roles'][0] : get_option('default_role')); ?>" name="role" />
Or, more robustly, inject it server-side on admin_init so it is always in sync with the user's selection regardless of template rendering order:
add_action('admin_init', function () {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
return;
}
// When AAM's multi-role field is present, always use the first selected
// role as $_POST['role'] so wp_ensure_editable_role() receives a valid,
// actually-editable role — not the site's default_role which may have
// been removed from get_editable_roles() by the site owner.
if (!isset($_POST['aam_user_roles'])) {
return;
}
$roles = (array) $_POST['aam_user_roles'];
if (!empty($roles[0])) {
$role = sanitize_text_field($roles[0]);
if (get_role($role)) {
$_POST['role'] = $role;
$_REQUEST['role'] = $role;
}
}
}, 0);
Verification
is_admin() → YES
current_user_can('promote_user', $user_id) → YES
get_editable_roles() → returns all custom roles correctly (but not subscriber)
- Deactivating AAM resolves the issue immediately
- Downgrading to AAM 7.1.0 resolves the issue (native
<select name="role"> is used instead)
Related
7.1.1 regression: "Sorry, you are not allowed to give users that role." when Multi-Role Support is enabled and
default_roleis not inget_editable_roles()Summary
AAM 7.1.1 introduced a regression that causes role assignment to fail with:
This affects single-site WordPress installs where Multi-Role Support is enabled and the site's WordPress default role (set via Settings → General) has been filtered out of
get_editable_roles()— for example by a theme or plugin using theeditable_rolesfilter.The error affects all users including administrators, and occurs on both
user-edit.phpanduser-new.php.Root Cause (with diff evidence)
The change introduced in 7.1.1 is in
application/Backend/tmpl/user/multiple-roles.php:+ <input type="hidden" value="<?php echo esc_js(get_option('default_role')); ?>" name="role" />This was intended to satisfy
wp_ensure_editable_role()(added in WordPress 6.7), which validates that$_POST['role']is present and corresponds to a role inget_editable_roles().The problem: the hidden field is hardcoded to
get_option('default_role')— typicallysubscriber— regardless of which role the user actually selected in AAM'saam_user_roles[]multi-select. If the site has filteredsubscriberout ofget_editable_roles()(a common pattern for sites that don't use built-in WP roles),wp_ensure_editable_role()sees an invalid role and callswp_die().Behaviour comparison
$_POST['role']onuser-edit.php<select name="role">(correct role)<input name="role">hardcoded toget_option('default_role')$_POST['aam_user_roles[]']wp_ensure_editable_role()resultdefault_role∉get_editable_roles()Environment
default_roleis excluded fromget_editable_roles()Steps to Reproduce
wp-admin/users.phpand click Edit on any userExpected Behaviour
The user's role is updated to the role selected in AAM's multi-role field.
Actual Behaviour
wp_ensure_editable_role()validates$_POST['role']which AAM 7.1.1 set toget_option('default_role')— a role that is not present inget_editable_roles()on this site.Suggested Fix
Instead of hardcoding
get_option('default_role')in the hidden field, use the first role fromaam_user_roles[]— the role the user actually selected:Or, more robustly, inject it server-side on
admin_initso it is always in sync with the user's selection regardless of template rendering order:Verification
is_admin()→ YEScurrent_user_can('promote_user', $user_id)→ YESget_editable_roles()→ returns all custom roles correctly (but notsubscriber)<select name="role">is used instead)Related
roleinput introduced this regression