{"record":{"id":"7400f74737536488","repo":"passbolt/passbolt_api","slug":"could-not-delete-the-resource-please-try-again-later","errorCode":null,"errorMessage":"Could not delete the resource. Please try again later.","messagePattern":"Could not delete the resource\\. Please try again later\\.","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"src/Controller/Resources/ResourcesDeleteController.php","lineNumber":109,"sourceCode":"            $originalResource = clone $resource;\n        } catch (RecordNotFoundException $e) {\n            throw new NotFoundException(__('The resource does not exist.'));\n        }\n\n        // Get the list of users who have access to the resource\n        // useful to do now to notify users later, since it wont be possible to after delete\n        // The logged in user will not be notified.\n        $options = ['contain' => ['role'], 'filter' => ['has-access' => [$resource->id]]];\n        $users = $this->Users\n            ->findIndex(Role::USER, $options)\n            ->find('locale')\n            ->where(['Users.id !=' => $this->User->id()])\n            ->all();\n\n        // Update the entity to delete=1, clear uri/desc/username and drop associated permissions\n        if (!$this->Resources->softDelete($this->User->id(), $resource)) {\n            $this->_handleDeleteError($resource);\n            throw new InternalErrorException('Could not delete the resource. Please try again later.');\n        }\n\n        $this->_notifyUser($originalResource, $users);\n        $this->success(__('The resource has been deleted successfully.'));\n    }\n\n    /**\n     * Manage delete errors.\n     *\n     * @param \\App\\Model\\Entity\\Resource $resource entity\n     * @throws \\Cake\\Http\\Exception\\NotFoundException\n     * @throws \\App\\Error\\Exception\\ValidationException\n     * @return void\n     */\n    protected function _handleDeleteError(Resource $resource): void\n    {\n        $errors = $resource->getErrors();\n        if (empty($errors)) {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Resources/ResourcesDeleteController.php#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif (!$this->Resources->softDelete($this->User->id(), $resource)) {\n    $this->_handleDeleteError($resource);\n    throw new InternalErrorException('Could not delete the resource. Please try again later.');\n}\n// after\nif (!$this->Resources->softDelete($this->User->id(), $resource)) {\n    $this->_handleDeleteError($resource);\n    $errors = $resource->getErrors();\n    $this->log('Resource soft delete failed: ' . json_encode($errors), 'error');\n    throw new InternalErrorException('Could not delete the resource. Please try again later.');\n}","handlingStrategy":"try-catch","validationCode":"// client: ensure resource exists and user is owner before delete\nconst r = await api.get(`/resources/${id}.json`);\nif (!r || r.permission.type < 7) throw new Error('Delete requires update/owner permission');","typeGuard":null,"tryCatchPattern":"try { await api.delete(`/resources/${id}.json`); } catch (e) { if (e.status === 500) { logRootCause(e); showRetryDialog(); } else throw e; }","preventionTips":["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"],"tags":["http-500","soft-delete","resources","persistence"],"backgroundTag":"database-write-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}