Site runs into error when new module permissions are set

Created on 16 October 2024, about 1 month ago

Problem/Motivation

I see the message "The website encountered an unexpected error. Try again later." when setting permissions for a newly enabled module. Whats the right approach to isolate the troublesome module, if any?

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

๐Ÿ’ฌ Support request
Status

Active

Version

10.2 โœจ

Component

user.module

Created by

๐Ÿ‡ฎ๐Ÿ‡ณIndia vallab444

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @vallab444
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia vallab444

    The error also appears when I click on the "Manage Permissions" tab for any Content Type, including Basic Page

  • Start by reading Drupalโ€™s logs, which is on the reports menu.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia vallab444

    Thank you, @cilefen. Maybe the first time I have made use of Drupal reports !

    What I found was rather weird. I'll explain and let me know if therein lies a bug.

    I had deleted two custom fields from my Content Type. And that was the root cause. Drupal was trying to assign roles to those 'non-existent fields' ! How is this even possible? Since I am still in dev phase, deleted the nodes that were previously using those deleted fields. And then added back these two fields. That solved the problem.

    Here's the error message:

    RuntimeException: Adding non-existent permissions to a role is not allowed. The incorrect permissions are "view field_number_of_scans". in Drupal\user\Entity\Role->calculateDependencies() (line 207 of /home3/brandwa1/public_html/core/modules/user/src/Entity/Role.php).

    I have never come across this situation, after deleting a field.

  • You could search the Internet for drupal "Adding non-existent permissions to a role is not allowed" as there have been prior reports. I don't know if there has been a definitive answer or whether this is caused by contributed modules with bugs.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia vallab444

    Okay. Thank you.

    As a layman, I can't comment on the tech part of it. Found that roles.yaml has got a piece explicitly to deal with this situation.

    We keep deleting fields, but it doesn't throw up this error always. So, as you said, contrib modules may be bringing in this element....

  • First commit to issue fork.
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia KumudB Ahmedabad

    I have tested this on local and it is working as expected, PHPUnit testing taking more time so here I am adding the code, Modified the Function to Automatically Handle Invalid Permissions

    /**
       * {@inheritdoc}
       */
      public function calculateDependencies() {
        parent::calculateDependencies();
        // Load all permission definitions.
        $permission_definitions = \Drupal::service('user.permissions')->getPermissions();
        $valid_permissions = array_intersect($this->permissions, array_keys($permission_definitions));
        $invalid_permissions = array_diff($this->permissions, $valid_permissions);
        if (!empty($invalid_permissions)) {
          \Drupal::logger('user')->warning('Removing non-existent permissions from role: "@permissions".', ['@permissions' => implode(', ', $invalid_permissions)]);
          // Remove invalid permissions from the role.
          $this->permissions = $valid_permissions;
        }
        foreach ($valid_permissions as $permission) {
          // Depend on the module that is providing this permissions.
          $this->addDependency('module', $permission_definitions[$permission]['provider']);
          // Depend on any other dependencies defined by permissions granted to
          // this role.
          if (!empty($permission_definitions[$permission]['dependencies'])) {
            $this->addDependencies($permission_definitions[$permission]['dependencies']);
          }
        }
        return $this;
      }

    Logging Instead of Throwing an Exception:
    Instead of throwing a RuntimeException, we log a warning using \Drupal::logger('user')->warning() when invalid permissions are found. This allows the system to recover from the error without breaking.

    Automatically Removing Invalid Permissions:
    The invalid permissions are removed from the role by resetting $this->permissions to $valid_permissions. This ensures that roles are no longer linked to non-existent permissions.

    Rest of the Logic Remains Unchanged:
    The valid permissions are processed as they were originally, adding necessary dependencies based on the permissions.

Production build 0.71.5 2024