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

  1. Check server logs and the exception chain to find the underlying save/database error reported by softDelete().
  2. Run pending migrations (ddev refresh / bin/cake migrations migrate) to ensure the resources table schema is current.
  3. Verify no custom plugins/behaviors add validation rules on the Resources entity that fail on soft delete.
  4. Retry the delete; if the resource was concurrently deleted, re-fetch it — it may already be soft-deleted.
  5. 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

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


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)