passbolt/passbolt_api · error · ValidationException
Could not delete the resource.
Error message
Could not delete the resource.
What it means
A 422 ValidationException raised by _handleDeleteError as the final fallback when softDelete() failed with validation errors that match neither the soft-deleted nor has_access rules. The exception carries the resource entity and ResourcesTable errors so clients can see which fields failed validation.
Solutions
- Read the error details in the 422 response body — they name the failing field and rule.
- Run pending migrations and clear cache to fix schema/plugin drift.
- Disable recently added resource-related plugins to identify which rule fails.
- Fix the offending resource data directly (e.g. via cake console) if a row is corrupted.
Example fix
// before
const resp = await fetch(deleteUrl, {method: 'DELETE'});
throw new Error('delete failed');
// after
const resp = await fetch(deleteUrl, {method: 'DELETE'});
if (resp.status === 422) {
const body = await resp.json();
console.error('Validation errors:', body.errors); // field-level detail
} Defensive patterns
Strategy: try-catch
Validate before calling
// surface the 422 error body to identify the failing field/rule before retrying
const resp = await fetch(`/resources/${id}.json`, {method: 'DELETE'});
if (resp.status === 422) { const {errors} = await resp.json(); inspect(errors); } Try / catch
try { await api.delete(`/resources/${id}.json`); } catch (e) { if (e.status === 422) showFieldErrors(e.body.errors); else throw e; } Prevention
- Read the 422 response body — it names the failing field and rule
- Keep plugins and migrations in sync across environments
- Audit custom validation rules on Resources when upgrades change behavior
When it happens
Trigger: DELETE /resources/{id}.json where a plugin-added or custom validation rule on the Resources entity fails during softDelete (any error key other than 'deleted.is_not_soft_deleted' or 'id.has_access').
Common situations: Custom plugins (e.g. metadata, folders) adding validation on resources, schema drift after an upgrade leaving fields in a state that fails rules, corrupted resource rows.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Could not delete the resource. Please try again later.
- Could not validate resource data.
- The metadata private key could not be validated.
- The metadata private key data is not valid.
- The resource identifier should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/9b8f0129725cff92.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Resources/ResourcesDeleteController.php:141
*/
protected function _handleDeleteError(Resource $resource): void
{
$errors = $resource->getErrors();
if (empty($errors)) {
return;
}
if (isset($errors['deleted']['is_not_soft_deleted'])) {
throw new NotFoundException(__('The resource does not exist.'));
}
if (isset($errors['id']['has_access'])) {
// If the user has a read access return a 403, otherwise return a 404 to avoid data leak.
$acoType = PermissionsTable::RESOURCE_ACO;
if ($this->Resources->Permissions->hasAccess($acoType, $resource->id, $this->User->id())) {
throw new ForbiddenException(__('You do not have the permission to delete this resource.'));
}
throw new NotFoundException(__('The resource does not exist.'));
}
throw new ValidationException(__('Could not delete the resource.'), $resource, $this->Resources);
}
/**
* Send email notification
*
* @param \App\Model\Entity\Resource $resource Resource
* @param \Cake\Datasource\ResultSetInterface $users Users who had access to the resource, deleter excluded
* @return void
*/
protected function _notifyUser(Resource $resource, ResultSetInterface $users): void
{
$event = new Event(static::DELETE_SUCCESS_EVENT_NAME, $this, [
'resource' => $resource,
'deletedBy' => $this->User->id(),
'users' => $users,
]);
$this->getEventManager()->dispatch($event);
}View on GitHub (pinned to 31c1bbc10f)