passbolt/passbolt_api · error · InternalErrorException
Could not delete the resource. Please try again later.
Error message
Could not delete the resource. Please try again later.
What it means
Thrown by ResourcesDeleteController::delete when ResourcesTable::softDelete() returns false, meaning the soft-delete save failed at the model layer. Before throwing, _handleDeleteError inspects the entity's validation errors to raise a more specific exception; this generic 500 is the fallback when no recognizable error rule matched (or no errors were set). It indicates an unexpected persistence failure, not a client mistake.
Solutions
- Check server logs and the exception chain to find the underlying save/database error reported by softDelete().
- Run pending migrations (ddev refresh / bin/cake migrations migrate) to ensure the resources table schema is current.
- Verify no custom plugins/behaviors add validation rules on the Resources entity that fail on soft delete.
- Retry the delete; if the resource was concurrently deleted, re-fetch it — it may already be soft-deleted.
- If reproducible, inspect ResourcesTable::softDelete() and add a specific _handleDeleteError branch for the failing rule.
Example fix
// before
if (!$this->Resources->softDelete($this->User->id(), $resource)) {
$this->_handleDeleteError($resource);
throw new InternalErrorException('Could not delete the resource. Please try again later.');
}
// after
if (!$this->Resources->softDelete($this->User->id(), $resource)) {
$this->_handleDeleteError($resource);
$errors = $resource->getErrors();
$this->log('Resource soft delete failed: ' . json_encode($errors), 'error');
throw new InternalErrorException('Could not delete the resource. Please try again later.');
} Defensive patterns
Strategy: try-catch
Validate before calling
// client: ensure resource exists and user is owner before delete
const r = await api.get(`/resources/${id}.json`);
if (!r || r.permission.type < 7) throw new Error('Delete requires update/owner permission'); Try / catch
try { await api.delete(`/resources/${id}.json`); } catch (e) { if (e.status === 500) { logRootCause(e); showRetryDialog(); } else throw e; } Prevention
- Keep server migrations and plugins up to date
- Monitor server logs for the underlying softDelete failure
- Treat persistent 500s as a server-side data/schema problem, not a client bug
When it happens
Trigger: DELETE /resources/{id}.json when softDelete() fails with validation errors other than 'deleted.is_not_soft_deleted' or 'id.has_access' (e.g. a database rule or attached behavior/save failure sets other error fields), or when softDelete fails without setting any entity errors.
Common situations: Database connectivity/schema issues (locked tables, missing migration), plugin behaviors attached to ResourcesTable altering save outcomes, concurrent delete race conditions where the resource was already soft-deleted with an unexpected error key, or a custom validation rule added by a plugin failing during softDelete.
Related errors
- Could not delete the resource.
- Could not save the comment, please try again later.
- Could not save the user data. Please try again later.
- The metadata private key could not be created. Please try…
- The metadata private keys could not be created.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/7400f74737536488.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Resources/ResourcesDeleteController.php:109
$originalResource = clone $resource;
} catch (RecordNotFoundException $e) {
throw new NotFoundException(__('The resource does not exist.'));
}
// Get the list of users who have access to the resource
// useful to do now to notify users later, since it wont be possible to after delete
// The logged in user will not be notified.
$options = ['contain' => ['role'], 'filter' => ['has-access' => [$resource->id]]];
$users = $this->Users
->findIndex(Role::USER, $options)
->find('locale')
->where(['Users.id !=' => $this->User->id()])
->all();
// Update the entity to delete=1, clear uri/desc/username and drop associated permissions
if (!$this->Resources->softDelete($this->User->id(), $resource)) {
$this->_handleDeleteError($resource);
throw new InternalErrorException('Could not delete the resource. Please try again later.');
}
$this->_notifyUser($originalResource, $users);
$this->success(__('The resource has been deleted successfully.'));
}
/**
* Manage delete errors.
*
* @param \App\Model\Entity\Resource $resource entity
* @throws \Cake\Http\Exception\NotFoundException
* @throws \App\Error\Exception\ValidationException
* @return void
*/
protected function _handleDeleteError(Resource $resource): void
{
$errors = $resource->getErrors();
if (empty($errors)) {View on GitHub (pinned to 31c1bbc10f)