Problem/Motivation
An error is thrown saving user permissions after D10 upgrade:
RuntimeException: Adding non-existent permissions to a role is not allowed. The incorrect permissions are "cancel users with role maintainer", "cancel users with role manager", "edit users with role maintainer", "edit users with role manager", "role-assign users with role maintainer", "role-assign users with role manager", "view users with role maintainer", "view users with role manager". in Drupal\user\Entity\Role->calculateDependencies() (line 207 of core\modules\user\src\Entity\Role.php). (full error w/ stack trace listed at bottom of issue)
It would seem that changing the Allowed Roles configuration in the module settings after setting some permissions creates invalid roles in the permissions table that are not cleaned up.
This was noted in the Drupal 10 upgrade log:
Invalid permissions will trigger runtime exceptions in Drupal 10. β
Steps to reproduce
- While upgrading to Drupal 10 using the Upgrade Status module, the module advises of some invalid permissions that appear to be generated by the module (e.x. cancel users with role ___). The fix for this is to export configuration, delete the problematic lines from user.role.____ configs, then import the configuration.
- To be safe, I also uninstalled this module to prevent issues.
- Drupal 10 core is upgraded successfully.
- After upgrade, with no PHP errors or runtime exceptions elsewhere, went to permission page and saved the page. No errors.
- Enabled this module.
- Configured some roles as Forbidden, some as Custom.
- Set some permissions for this module based on Custom roles from previous step.
- Saved permissions. No errors.
- Changed role configuration so some were Allowed and some were Custom.
- Updated the permissions based on my changes.
- After saving the permissions page, the RuntimeException is thrown.
If I do the same fix as indicated in Step 1 (export config, remove bad permissions, import config) and clear the cache, I am again able to save permissions.
Proposed resolution
Update module code so that changing the allowed roles in the module settings page removes the impacted permissions from the permissions table.
Remaining tasks
User interface changes
None should be needed
API changes
Data model changes
Full error:
RuntimeException: Adding non-existent permissions to a role is not allowed. The incorrect permissions are "cancel users with role maintainer", "cancel users with role manager", "edit users with role maintainer", "edit users with role manager", "role-assign users with role maintainer", "role-assign users with role manager", "view users with role maintainer", "view users with role manager". in Drupal\user\Entity\Role->calculateDependencies() (line 207 of core\modules\user\src\Entity\Role.php).
Drupal\Core\Config\Entity\ConfigEntityBase->preSave() (Line: 179)
Drupal\user\Entity\Role->preSave() (Line: 528)
Drupal\Core\Entity\EntityStorageBase->doPreSave() (Line: 483)
Drupal\Core\Entity\EntityStorageBase->save() (Line: 257)
Drupal\Core\Config\Entity\ConfigEntityStorage->save() (Line: 339)
Drupal\Core\Entity\EntityBase->save() (Line: 609)
Drupal\Core\Config\Entity\ConfigEntityBase->save() (Line: 990)
user_role_grant_permissions() (Line: 964)
user_role_change_permissions() (Line: 228)
Drupal\user\Form\UserPermissionsForm->submitForm()
call_user_func_array() (Line: 114)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers() (Line: 52)
Drupal\Core\Form\FormSubmitter->doSubmitForm() (Line: 597)
Drupal\Core\Form\FormBuilder->processForm() (Line: 325)
Drupal\Core\Form\FormBuilder->buildForm() (Line: 224)
Drupal\Core\Form\FormBuilder->getForm() (Line: 66)
Drupal\fpa\FpaFormBuilder::buildFpaPage() (Line: 24)
Drupal\fpa\Controller\FPAController->permissionsList()
call_user_func_array() (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 583)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 166)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 74)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 58)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 704)
Drupal\Core\DrupalKernel->handle() (Line: 19)