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
- Call GET /roles to confirm the role still exists and copy its current ID.
- If the role was already deleted, treat the operation as done — no retry needed.
- If the ID should exist, check whether it was soft-deleted in the DB (roles.deleted = true).
- 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
- Treat 404 on delete as idempotent success in retry logic
- Refetch the roles list after any delete before further mutations
- Invalidate cached role lists on deletion
- Handle double-submits by ignoring 404 on repeated deletes
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
- The role does not exist or deleted.
- The role could not be deleted.
- Could not delete the role, please try again later.
- Could not save the role, please try again later.
- Could not update the role, please try again later.
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)