passbolt/passbolt_api · warning · Cake\Http\Exception\BadRequestException
Multiple has-access filters are not supported.
Error message
Multiple has-access filters are not supported.
What it means
BadRequestException (HTTP 400) from UsersIndexController::assertHasAccess: the `filter[has-access]` query parameter was supplied with more than one resource id. The endpoint only supports checking access against a single resource per request.
Solutions
- Issue one request per resource id, each with a single has-access value.
- Change client code to send only the first/selected resource id, or loop over ids.
- If bulk checks are needed, batch client-side across multiple single-id requests.
Example fix
// before
const ids = ['res-1', 'res-2'];
await api.getUsers({ filter: { 'has-access': ids } });
// after
const results = await Promise.all(ids.map(id =>
api.getUsers({ filter: { 'has-access': [id] } })
)); Defensive patterns
Strategy: validation
Validate before calling
function assertSingleHasAccess(filter) {
const ids = filter?.['has-access'];
if (Array.isArray(ids) && ids.length > 1) throw new Error('has-access accepts at most one resource id');
} Try / catch
try { await api.getUsers({ filter: { 'has-access': ids } }); } catch (e) { if (e.code === 400 && /Multiple has-access/.test(e.message)) { return Promise.all(ids.map(id => api.getUsers({ filter: { 'has-access': [id] } }))); } throw e; } Prevention
- Enforce one-resource-per-request semantics in client filter builders.
- Deduplicate and cap the has-access filter before sending.
- Handle 400 responses by falling back to per-id requests.
When it happens
Trigger: GET /users.json?filter[has-access]=<uuid1>,<uuid2> (or repeated has-access filters) — i.e. any request where the has-access filter array contains 2+ entries.
Common situations: Client code passing an array of resource ids assuming multi-resource support; UI selecting multiple resources and forwarding all ids; combining comma-joined values into the filter.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- Conflicting authentication parameters, provide…
- Invalid filter.
- Invalid query string. The contain parameter should be an…
- Invalid query string. The filter parameter should be an…
- Some user data should be provided.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/4bb90f49c3e44ed7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Users/UsersIndexController.php:134
$computedFindIndexOptions
);
}
$this->paginate($users);
$this->success(__('The operation was successful.'), $users);
}
/**
* @throws \Cake\Http\Exception\ForbiddenException if user doesn't have access to the resource requested by the filter
* @throws \Cake\Http\Exception\BadRequestException if multiple has-access filters are requested
* @param array $options from
* @return void
*/
public function assertHasAccess(array $options): void
{
if (isset($options['filter']['has-access']) && count($options['filter']['has-access'])) {
if (count($options['filter']['has-access']) > 1) {
throw new BadRequestException(__('Multiple has-access filters are not supported.'));
}
$resourceId = $options['filter']['has-access'][0];
$service = new UserHasPermissionService();
if (!$service->check(PermissionsTable::RESOURCE_ACO, $resourceId, $this->User->id())) {
throw new ForbiddenException(__('This operation is not allowed for this user.'));
}
}
}
}
View on GitHub (pinned to 31c1bbc10f)