passbolt/passbolt_api · error · ConflictException
The user cannot be deleted because its the sole owner of…
Error message
The user cannot be deleted because its the sole owner of shared content
What it means
Raised in UserScimResource::delete() when the SCIM user deletion fails because the CakePHP Users table validation produced a 'soleOwnerOfSharedContent' error on the id field. Passbolt refuses to soft-delete a user who is the only owner of passwords/folders shared with others, since deletion would orphan shared content. It surfaces as an HTTP 409 Conflict on the SCIM /Users DELETE endpoint.
Solutions
- Before deleting, transfer ownership of the shared items: log in as another admin (or via API) and share/change owner of the user's personal folders and passwords with another user, then retry the DELETE.
- Delete or reassign the shared resources via the passbolt UI/API so the user no longer solely owns shared content.
- If business rules allow, disable the user instead of deleting (SCIM PATCH active=false) so content stays accessible.
- Check the server error log / ScimLog for the exact validation errors to confirm the sole-owner condition.
Example fix
// before (fails) DELETE /scim/v2.0/Users/8a4b... // user owns shared folder alone // after: share the folder with another owner first, then DELETE /scim/v2.0/Users/8a4b... // 204 No Content
Defensive patterns
Strategy: try-catch
Validate before calling
// Before deleting via SCIM, check the user still exists
$resp = $client->get("/scim/v2.0/Users/{$id}");
if ($resp->getStatusCode() !== 200) { return; } // already gone, nothing to do Try / catch
try {
$client->delete("/scim/v2.0/Users/{$id}");
} catch (ClientException $e) {
if ($e->getResponse()->getStatusCode() === 409
&& str_contains((string)$e->getResponse()->getBody(), 'sole owner of shared content')) {
// transfer ownership then retry
} else { throw $e; }
} Prevention
- Transfer/reassign ownership of shared folders and passwords before offboarding a user.
- Prefer SCIM PATCH active=false (disable) over hard delete for users who own shared content.
- Verify with an admin that the departing user is not the sole owner of team content.
- Handle 409 as an expected offboarding outcome, not a bug.
When it happens
Trigger: DELETE /scim/v2.0/Users/{id} where the target user is the sole owner of folders/passwords shared with other users (e.g. an offboarded admin who shared credentials with the team and nobody else has ownership).
Common situations: IdP-driven SCIM deprovisioning (Okta, Azure AD) disabling/deleting a user; cleanup scripts deleting admins who created most shared items; automated offboarding without ownership transfer first.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The User resource could not be deleted due to validation…
- Please delete previous settings before creating again.
- The resource could not be created due to a uniqueness…
- The resource with id ` ` could not be created due to a…
- Unexpected error when trying to delete the user.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/bbf71739d0cf52d2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Scim/src/Utility/Resource/UserScimResource.php:955
{
if (!$this->userEntity) {
throw new ScimException(
sprintf(
'The values of the %s resource has not been set for the `delete` operation',
$this->getType()
)
);
}
$this->assertAdminDeleteAllowed();
try {
$result = $this->Users->softDelete($this->userEntity);
$errors = $this->userEntity->getErrors();
if (!$result || $errors !== []) {
if (isset($errors['id']['soleOwnerOfSharedContent'])) {
// @todo: send email
throw new ConflictException(
'The user cannot be deleted because its the sole owner of shared content'
);
}
throw new ConflictException('The User resource could not be deleted due to validation failure');
}
} catch (Exception $e) {
ScimLog::error(sprintf('Unable to delete the user with id `%s`', $this->userEntity->id));
ScimLog::error($e->getMessage());
ScimLog::error($e->getTraceAsString());
throw new ConflictException('Unexpected error when trying to delete the user.');
}
return $this;
}
/**
* @inheritDocView on GitHub (pinned to 31c1bbc10f)