{"record":{"id":"8ac3dc312768079a","repo":"passbolt/passbolt_api","slug":"the-resource-does-not-exist-resourcesdeletecontroller","errorCode":null,"errorMessage":"The resource does not exist.","messagePattern":"The resource does not exist\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Controller/Resources/ResourcesDeleteController.php","lineNumber":93,"sourceCode":"    public function delete(string $id): void\n    {\n        $this->assertJson();\n\n        // Check request sanity\n        if (!Validation::uuid($id)) {\n            throw new BadRequestException(__('The resource identifier should be a valid UUID.'));\n        }\n\n        // Retrieve the resource to delete.\n        try {\n            /** @var \\App\\Model\\Entity\\Resource $resource */\n            $resource = $this->Resources->find()\n                ->contain(['ResourceTypes'])\n                ->where(['Resources.id' => $id])\n                ->firstOrFail();\n            $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","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Resources/ResourcesDeleteController.php#L75-L111","documentation":"Passbolt throws this 404 when DELETE /resources/<id> uses a valid UUID but the resource lookup (find()->where(Resources.id)->firstOrFail()) throws RecordNotFoundException. The resource simply isn't in the database (or its resource type row is missing via the contain).","triggerScenarios":"Deleting an already-deleted resource (double delete / race between two clients); UUID from a different environment; a resource whose ResourceTypes row is absent so the contain leaves it unjoinable.","commonSituations":"Optimistic-concurrency bugs where two tabs delete the same resource; restore/migration scripts replaying deletions; test fixtures referencing production ids; broken resource_types data after manual DB edits.","solutions":["Make deletion idempotent: treat 404 on DELETE as success in cleanup/sync scripts","Refresh the resource list and verify the id still exists before deleting","Check the resource_types table has a matching type row for the resource","Reconcile environments if the id came from another instance"],"exampleFix":"// before\nawait api.del(`/resources/${id}.json`); // throws on 404\n// after\ntry {\n  await api.del(`/resources/${id}.json`);\n} catch (e) {\n  if (e.status !== 404) throw e; // already deleted: ok\n}","handlingStrategy":"try-catch","validationCode":"const stillThere = (await fetch('/resources.json').then(r=>r.json())).body.some(r=>r.id===resourceId);\nif (!stillThere) return { deleted: true, alreadyGone: true };","typeGuard":"null","tryCatchPattern":"try {\n  await deleteResource(id);\n} catch (e) {\n  if (e.status === 404) return { deleted: true }; // idempotent delete\n  throw e;\n}","preventionTips":["Make deletes idempotent — another client may have deleted first","Refresh resource lists before batch deletions","Never replay recorded delete operations against a restored database without existence checks"],"tags":["http-404","resources","delete","rest-api"],"backgroundTag":"entity-not-found","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"}