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
- Confirm the resource exists and is shared with the user via GET /resources.json (list shows only accessible items)
- Re-check that the user still has permission on the resource; re-share if it was revoked
- Verify the id against the resource index rather than a cached/stale value
- 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
- Only query permissions for resources returned by your own /resources.json listing
- Remember the lookup is access-scoped: 404 may mean no permission, not non-existence
- Re-share or refresh after permission changes
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
- The resource does not exist.
- The resource does not exist.
- The favorite does not exist.
- The group does not exist.
- The group does not exist.
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)