bitwarden/server · error · BadRequestException
Requested collections must belong to the same organization.
Error message
Requested collections must belong to the same organization.
What it means
A BadRequestException (HTTP 400) thrown by BulkCollectionAuthorizationHandler when a bulk collection operation targets collections that do not all belong to the same organization. The handler takes the first collection's OrganizationId as the target and rejects the request if any collection in the batch has a different OrganizationId. This enforces single-org scope for bulk collection authorization.
Source
Thrown at src/Api/AdminConsole/Authorization/Collections/BulkCollectionAuthorizationHandler.cs:65
if (resources == null || !resources.Any())
{
context.Fail();
return;
}
// Acting user is not authenticated, fail
if (!_currentContext.UserId.HasValue)
{
context.Fail();
return;
}
_targetOrganizationId = resources.First().OrganizationId;
// Ensure all target collections belong to the same organization
if (resources.Any(tc => tc.OrganizationId != _targetOrganizationId))
{
throw new BadRequestException("Requested collections must belong to the same organization.");
}
var org = _currentContext.GetOrganization(_targetOrganizationId);
var authorized = false;
switch (requirement)
{
case not null when requirement == BulkCollectionOperations.Create:
authorized = await CanCreateAsync(org);
break;
case not null when requirement == BulkCollectionOperations.Read:
case not null when requirement == BulkCollectionOperations.ReadAccess:
authorized = await CanReadAsync(resources, org);
break;
case not null when requirement == BulkCollectionOperations.ReadWithAccess:View on GitHub (pinned to e93b962371)
Solutions
- Ensure all collection IDs in a single bulk request belong to the same organization.
- On the client, partition collection IDs by OrganizationId and issue separate bulk requests per org.
- Validate the collection list client-side before sending: group by org and assert a single group.
- If building a bulk API client, add a pre-flight check that loads collection org IDs and splits the batch.
Example fix
// before: mixing collections from different orgs var allCollectionIds = orgACollections.Concat(orgBCollections).ToList(); await api.BulkUpdateCollectionsAsync(allCollectionIds, ...); // after: split by organization await api.BulkUpdateCollectionsAsync(orgACollections, ...); await api.BulkUpdateCollectionsAsync(orgBCollections, ...);
Defensive patterns
Strategy: validation
Validate before calling
// Group collections by org before issuing a bulk request
var grouped = collections.GroupBy(c => c.OrganizationId);
if (grouped.Count() > 1)
throw new InvalidOperationException("Cannot bulk-operate on collections from multiple organizations.");
foreach (var group in grouped)
await api.BulkCollectionOpAsync(group.Select(c => c.Id).ToList()); Type guard
static bool AllSameOrg(IEnumerable<Collection> collections)
=> collections.Select(c => c.OrganizationId).Distinct().Count() <= 1; Try / catch
try { await api.BulkUpdateCollectionsAsync(collectionIds, ...); }
catch (BadRequestException ex) when (ex.Message.Contains("same organization"))
{ /* Split the batch by org and retry each group separately */ } Prevention
- In bulk-select UIs, prevent selecting collections across org boundaries.
- Build a client-side helper that partitions collection IDs by OrganizationId before any bulk call.
- Add an integration test that sends a mixed-org batch and asserts a 400 response.
When it happens
Trigger: A bulk collection API call (create, read, update, delete, access modification) includes collection IDs from two or more different organizations in a single request. The handler detects the mismatch before evaluating per-collection permissions.
Common situations: A client bug concatenates collection IDs from multiple org contexts into one bulk request. A user has collections from multiple orgs in their vault and a bulk-select UI inadvertently mixes them. API misuse by a script or integration that doesn't scope by org.
Related errors
- Route parameter 'orgId' or 'organizationId' is missing or in
- Route parameter 'orgId' or 'organizationId' is missing or in
- Route parameter '{attr.OrganizationUserIdRouteParam}' is mis
- One or more collections not found.
- You cannot add yourself to groups.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/4a2d1346779f3dca.
Report an issue: GitHub.