BookStackApp/BookStack · error · PermissionsException

errors.role_registration_default_cannot_delete

Error message

errors.role_registration_default_cannot_delete

What it means

PermissionsRepo::deleteRole also blocks deletion of the role configured as the default role for new registrations (setting 'registration-role'). Deleting it would leave new sign-ups without a valid role, so a PermissionsException is thrown.

Source

Thrown at app/Permissions/PermissionsRepo.php:136

    /**
     * Delete a role from the system.
     * Check it's not an admin role or set as default before deleting.
     * If a migration Role ID is specified, the users assigned to the current role
     * will be added to the role of the specified id.
     *
     * @throws PermissionsException
     * @throws Exception
     */
    public function deleteRole(int $roleId, int $migrateRoleId = 0): void
    {
        $role = $this->getRoleById($roleId);

        // Prevent deleting admin role or default registration role.
        if ($role->system_name && in_array($role->system_name, $this->systemRoles)) {
            throw new PermissionsException(trans('errors.role_system_cannot_be_deleted'));
        } elseif ($role->id === intval(setting('registration-role'))) {
            throw new PermissionsException(trans('errors.role_registration_default_cannot_delete'));
        }

        (new DatabaseTransaction(function () use ($migrateRoleId, $role) {
            if ($migrateRoleId !== 0) {
                $newRole = Role::query()->find($migrateRoleId);
                if ($newRole) {
                    $users = $role->users()->pluck('id')->toArray();
                    $newRole->users()->sync($users);
                }
            }

            $role->entityPermissions()->delete();
            $role->jointPermissions()->delete();
            Activity::add(ActivityType::ROLE_DELETE, $role);
            $role->delete();
        }))->run();
    }
}

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Change the default registration role first (Settings > Registration > Default user role, or setting 'registration-role') to another role, then delete the old one
  2. Skip the default-registration role in bulk-delete scripts the same way system roles are skipped
  3. If the setting points to the wrong role id, correct the setting value in the settings table
  4. Check the error vs. error 121: if it's not a system role, it's this registration-default check

Example fix

// before
$repo->deleteRole($oldRoleId);
// after
if (intval(setting('registration-role')) !== $oldRoleId) {
    $repo->deleteRole($oldRoleId);
} else {
    // set another role as registration default first
}
Defensive patterns

Strategy: validation

Validate before calling

$defaultRegRole = intval(setting('registration-role'));
if ($roleId === $defaultRegRole) {
    throw new \InvalidArgumentException('Change the default registration role before deleting this role');
}

Type guard

function isDefaultRegistrationRole(int $roleId, $settings): bool {
    return $roleId === intval($settings->get('registration-role'));
}

Try / catch

try {
    $repo->deleteRole($roleId);
} catch (\BookStack\Exceptions\PermissionsException $e) {
    if (str_contains($e->getMessage(), 'role_registration_default_cannot_delete')) {
        // prompt admin to pick a new default registration role first
    }
}

Prevention

When it happens

Trigger: Calling deleteRole($roleId) where $role->id equals intval(setting('registration-role')); also occurs via the role-management UI when deleting the default registration role.

Common situations: Admins cleaning up unused roles without realizing one is the registration default; scripts bulk-deleting roles after a migration; environments where the setting points at an unexpected role.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/7ccfc0e9449e40d5. Report an issue: GitHub.