passbolt/passbolt_api · error · NotFoundException

The resource does not exist.

Error message

The resource does not exist.

What it means

Thrown by SecretRevisionsResourceGetController::get() when Resources->findView($userId, $resourceId) returns no row, meaning the resource either does not exist or the authenticated user lacks access to it (findView applies ACL). NotFoundException maps to HTTP 404.

Solutions

  1. Confirm the resource exists and is visible to the user via GET /resources/:id before fetching revisions
  2. Grant the requesting user access (share the resource) if the intent is to allow revision reads
  3. Verify you are hitting the intended environment/database
  4. Handle 404 in the client by refreshing the resource list
Defensive patterns

Strategy: try-catch

Validate before calling

const resource = await api.getResource(resourceId); // will 404 early if absent/inaccessible
if (!resource) return null;

Try / catch

try {
  const revisions = await api.getSecretRevisionsForResource(resourceId);
} catch (e) {
  if (e.status === 404) { /* resource deleted or no permission — refresh list */ }
  throw e;
}

Prevention

When it happens

Trigger: GET secret revisions for a resource ID that is absent, already deleted, or invisible to the requesting user because permission is missing.

Common situations: Resource hard-deleted or soft-deleted before the call; user not shared on the resource (permission not granted); querying the wrong environment's database; stale ID cached in a UI after deletion.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/d321708ad100f12f. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/SecretRevisions/src/Controller/SecretRevisionsResourceGetController.php:71

    {
        $this->assertJson();

        // Check request sanity
        if (!Validation::uuid($resourceId)) {
            throw new BadRequestException(__('The resource identifier should be a valid UUID.'));
        }

        // Retrieve and sanity the query options.
        $whitelist = ['contain' => [
            'creator', 'creator.profile', 'secret',
        ]];
        $options = $this->QueryString->get($whitelist);

        // Retrieve the resource.
        /** @var \App\Model\Entity\Resource $resource */
        $resource = $this->Resources->findView($this->User->id(), $resourceId)->first();
        if (empty($resource)) {
            throw new NotFoundException(__('The resource does not exist.'));
        }

        // Filter by secrets by userId and the revision by secret revision
        $secretRevisionsBaseQuery = $this->Resources->SecretRevisions
            ->find()
            ->innerJoinWith('Secrets', function (Query $q) {
                return $q->where(['Secrets.user_id' => $this->User->id()]);
            })
            ->where(['SecretRevisions.resource_id' => $resourceId]);

        if ($options['contain']['secret'] ?? false) {
            $secretRevisionsBaseQuery->contain('Secrets', function (Query $q) {
                return $q->where(['Secrets.user_id' => $this->User->id()]);
            });
        }
        if ($options['contain']['creator'] ?? false) {
            $secretRevisionsBaseQuery->contain('Creator');
        }

View on GitHub (pinned to 31c1bbc10f)