passbolt/passbolt_api · error · NotFoundException

The resource does not exist.

Error message

The resource does not exist.

What it means

Passbolt throws this 404 when the acoForeignKey is a valid UUID but Resources->findView() returns no row the requesting user can see. The lookup is access-scoped, so the resource may exist yet still be invisible to this user.

Solutions

  1. Confirm the resource exists and is shared with the user via GET /resources.json (list shows only accessible items)
  2. Re-check that the user still has permission on the resource; re-share if it was revoked
  3. Verify the id against the resource index rather than a cached/stale value
  4. Confirm client and server point to the same environment

Example fix

// before
const perms = await fetch(`/permissions/resource/${resourceId}.json`);
// after
const visible = await fetch('/resources.json').then(r => r.json());
if (!visible.body.some(r => r.id === resourceId)) {
  throw new Error('resource not accessible to current user');
}
const perms = await fetch(`/permissions/resource/${resourceId}.json`);
Defensive patterns

Strategy: try-catch

Validate before calling

const visible = (await fetch('/resources.json').then(r=>r.json())).body;
if (!visible.some(r=>r.id===resourceId)) throw new Error('resource not visible to current user');

Type guard

null

Try / catch

try {
  return await fetchPermissions(resourceId);
} catch (e) {
  if (e.status === 404) return { permissions: [], note: 'resource not found or not shared' };
  throw e;
}

Prevention

When it happens

Trigger: GET /permissions/resource/<uuid>.json where the resource was deleted, the UUID belongs to another instance, or the requesting user has no permission entry for that resource (findView filters by access).

Common situations: A user probing resource ids hoping to detect existence (correctly gets 404); stale UI after the resource was deleted or the user's permission was revoked; environment mismatch between API client data and server.

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/2c07b4221a212b9a. Report an issue: GitHub.

Appendix: source

Thrown at src/Controller/Permissions/PermissionsViewController.php:79

     * @return void
     */
    public function viewAcoPermissions(string $acoForeignKey)
    {
        $this->assertJson();

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

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

        // Check that the user has access to the resource.
        $resource = $this->Resources->findView($this->User->id(), $acoForeignKey)->first();
        if (empty($resource)) {
            throw new NotFoundException(__('The resource does not exist.'));
        }

        // Retrieve the permissions.
        $permissions = $this->Permissions->findViewAcoPermissions($acoForeignKey, $options);
        $this->success(__('The operation was successful.'), $permissions);
    }
}

View on GitHub (pinned to 31c1bbc10f)