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

  1. Ensure all collection IDs in a single bulk request belong to the same organization.
  2. On the client, partition collection IDs by OrganizationId and issue separate bulk requests per org.
  3. Validate the collection list client-side before sending: group by org and assert a single group.
  4. 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

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


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/4a2d1346779f3dca. Report an issue: GitHub.