passbolt/passbolt_api · error · NotFoundException

The role does not exist or deleted.

Error message

The role does not exist or deleted.

What it means

RolesDeleteService::delete throws this NotFoundException when no non-deleted role matches the given UUID (firstOrFail on the notDeleted finder raises RecordNotFoundException). It means the role was already soft-deleted or never existed.

Solutions

  1. Call GET /roles to confirm the role still exists and copy its current ID.
  2. If the role was already deleted, treat the operation as done — no retry needed.
  3. If the ID should exist, check whether it was soft-deleted in the DB (roles.deleted = true).
  4. Ensure client caches of role lists are invalidated after deletions.

Example fix

// before
DELETE /roles/<already-deleted-id> -> 404 The role does not exist or deleted
// after
GET /roles  # verify list, only delete existing IDs
DELETE /roles/<existing-id> -> 200
Defensive patterns

Strategy: try-catch

Validate before calling

const roles = await api.listRoles();
if (!roles.some(r => r.id === roleId)) {
  console.warn('Role no longer exists; skip delete');
}

Type guard

function roleExists(roles, id) {
  return Array.isArray(roles) && roles.some(r => r && r.id === id);
}

Try / catch

try {
  await api.deleteRole(roleId);
} catch (e) {
  if (e.status === 404 && /does not exist or deleted/i.test(e.message)) {
    // already deleted or never existed: treat as idempotent success
  } else throw e;
}

Prevention

When it happens

Trigger: DELETE /roles/{uuid} for an ID that is not in the roles table, or one whose deleted flag is set (previously soft-deleted role).

Common situations: Deleting the same role twice (double-submit or retry after a slow response), stale cached role list referencing an already-removed role, or a typo'd UUID from hand-built requests.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/475c045da004c4a0. Report an issue: GitHub.

Appendix: source

Thrown at src/Service/Roles/RolesDeleteService.php:67

    /**
     * @param \App\Utility\UserAccessControl $uac UAC object.
     * @param string $roleId Role identifier to update.
     * @return void
     */
    public function delete(UserAccessControl $uac, string $roleId): void
    {
        $uac->assertIsAdmin();

        if (!Validation::uuid($roleId)) {
            throw new BadRequestException(__('The role identifier is not valid.'));
        }

        try {
            /** @var \App\Model\Entity\Role $role */
            $role = $this->Roles->find('notDeleted')->where(['id' => $roleId])->firstOrFail();
        } catch (RecordNotFoundException $e) {
            throw new NotFoundException(__('The role does not exist or deleted.'), null, $e);
        }

        $role = $this->softDeleteRole($role, $uac);

        $this->dispatchEvent(self::AFTER_ROLE_DELETE_SUCCESS_EVENT_NAME, [
            'uac' => $uac,
            'role' => $role,
        ]);
    }

    /**
     * @param \App\Model\Entity\Role $role Role entity.
     * @param \App\Utility\UserAccessControl $uac User Access Control.
     * @return \App\Model\Entity\Role
     */
    private function softDeleteRole(Role $role, UserAccessControl $uac): Role
    {
        $data = [

View on GitHub (pinned to 31c1bbc10f)