passbolt/passbolt_api · error · NotFoundException
The group does not exist.
Error message
The group does not exist.
What it means
Passbolt throws this 404 when updating a group whose id is syntactically a valid UUID but does not match any row in the groups table. GroupsUpdateController::assertRequestParameter checks Groups->exists(['id' => $id]) before doing anything else and fails fast so no permission checks run on a non-existent group.
Solutions
- List groups via GET /groups.json and confirm the target id exists, then retry with a valid id
- Check the groups table (SELECT id FROM groups WHERE id='<id>') to verify presence in the connected database
- If the group was deleted, recreate it or update the calling client to use the current group id
- Ensure the client is pointed at the intended environment (the id may exist elsewhere)
Example fix
// before
await fetch(`/groups/${staleGroupId}.json`, {method: 'PUT', ...});
// after
const groups = await fetch('/groups.json').then(r => r.json());
const group = groups.body.find(g => g.name === 'Marketing');
await fetch(`/groups/${group.id}.json`, {method: 'PUT', ...}); Defensive patterns
Strategy: validation
Validate before calling
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!UUID_RE.test(groupId)) throw new Error('invalid group id');
const exists = (await fetch('/groups.json').then(r=>r.json())).body.some(g=>g.id===groupId);
if (!exists) throw new Error(`group ${groupId} not found on this instance`); Type guard
const isUuid = (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v); Try / catch
try {
await passbolt.group.update(groupId, payload);
} catch (e) {
if (e.status === 404 && /group does not exist/i.test(e.message)) {
// refresh id from /groups.json and retry once
} else throw e;
} Prevention
- Resolve ids from the groups index endpoint instead of caching them long-term
- Treat 404 on group mutations as 're-sync id list' signal
- Never hardcode group UUIDs from docs or other environments
When it happens
Trigger: Calling PUT /groups/<id> (or its dry-run variant) with an id that is a valid UUID but was never created, was already deleted, or belongs to another environment's database.
Common situations: Stale URLs/bookmarks after a group was deleted; copying an id from a different install or test fixture; a client caching group ids after a purge/migration; hardcoding ids from documentation examples.
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 group does not exist.
- The group does not exist.
- Could not validate group data.
- The favorite does not exist.
- The group id is not valid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/79d33a719a56c4dc.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Groups/GroupsUpdateController.php:131
/**
* Assert the request parameter.
*
* @param \App\Utility\UserAccessControl $uac The operator
* @param string $id group uuid
* @return void
* @throws \Cake\Http\Exception\ForbiddenException If the operator is not a group manager or an admin
* @throws \Cake\Http\Exception\BadRequestException if the group uuid id invalid
*/
protected function assertRequestParameter(UserAccessControl $uac, string $id)
{
if (!Validation::uuid($id)) {
throw new BadRequestException(__('The group id is not valid.'));
}
$exists = $this->Groups->exists(['id' => $id]);
if (!$exists) {
throw new NotFoundException(__('The group does not exist.'));
}
// If the user is not manager of the group nor admin
$isGroupManager = $this->GroupsUsers->isManager($uac->getId(), $id);
$isAdmin = $uac->isAdmin();
if (!$isGroupManager && !$isAdmin) {
throw new ForbiddenException(__('You are not authorized to access that location.'));
}
}
/**
* Get and format the request data.
*
* @return array
*/
protected function _formatRequestData()
{
$data = $this->request->getData();View on GitHub (pinned to 31c1bbc10f)