bitwarden/server · error · BadRequestException
One or more collections do not belong to this organization.
Error message
One or more collections do not belong to this organization.
What it means
Thrown by AccessRuleWriteValidator.ValidateCollectionsAsync (line 79) when all collections exist but at least one belongs to a different organization (c.OrganizationId != organizationId). This prevents cross-organization collection assignment to an access rule.
Source
Thrown at bitwarden_license/src/Services/Pam/Services/AccessRuleWriteValidator.cs:79
private async Task<List<Guid>> ValidateCollectionsAsync(Guid organizationId, IEnumerable<Guid> collectionIds,
Guid? existingRuleId)
{
var distinctIds = collectionIds.Distinct().ToList();
if (distinctIds.Count == 0)
{
return distinctIds;
}
var collections = await _collectionRepository.GetManyByManyIdsAsync(distinctIds);
if (collections.Count != distinctIds.Count)
{
throw new BadRequestException("One or more collections could not be found.");
}
if (collections.Any(c => c.OrganizationId != organizationId))
{
throw new BadRequestException("One or more collections do not belong to this organization.");
}
// Deletes clear Collection.AccessRuleId and the FK forbids dangling links, so any set link points at an
// existing rule; only a link to a different rule is a conflict. A rule being created has no id, so for it
// any link at all conflicts.
if (collections.Any(c => c.AccessRuleId.HasValue && c.AccessRuleId != existingRuleId))
{
throw new BadRequestException("One or more collections are already governed by another access rule.");
}
return distinctIds;
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Filter collection IDs to only those belonging to the same organization before submission.
- Query collections by organization: _collectionRepository.GetManyByOrganizationIdAsync(orgId) and intersect with the requested IDs.
- Audit the API client to ensure it scopes collection lookups to the correct organizationId.
Example fix
// before — pass raw collection IDs that may span orgs await _validator.ValidateAsync(orgId, rule, requestedCollectionIds); // after — filter to same-org collections first var orgCollections = await _collectionRepository.GetManyByOrganizationIdAsync(orgId); var orgCollectionIds = orgCollections.Select(c => c.Id).ToHashSet(); var safeIds = requestedCollectionIds.Where(id => orgCollectionIds.Contains(id)); await _validator.ValidateAsync(orgId, rule, safeIds);
Defensive patterns
Strategy: validation
Validate before calling
var orgCollections = await _collectionRepository.GetManyByOrganizationIdAsync(organizationId);
var orgIds = orgCollections.Select(c => c.Id).ToHashSet();
var crossOrg = collectionIds.Where(id => !orgIds.Contains(id)).ToList();
if (crossOrg.Count > 0)
return BadRequest($"Collections do not belong to org {organizationId}: {string.Join(", ", crossOrg)}"); Try / catch
try { await _validator.ValidateAsync(orgId, rule, collectionIds); }
catch (BadRequestException ex) when (ex.Message.Contains("do not belong"))
{ /* scope collection picker to current org */ } Prevention
- Scope the collection picker UI to the current organization only.
- Never share collection IDs across org contexts in API clients.
- Add org-scoping filters at the API gateway or service layer.
When it happens
Trigger: The collectionIds list includes one or more Collection GUIDs whose OrganizationId differs from the organizationId the access rule belongs to. The check uses collections.Any(c => c.OrganizationId != organizationId).
Common situations: Admin has access to multiple orgs and picks a collection from the wrong org; collection IDs are shared across orgs in a multi-tenant dev/staging setup; API client sends collection IDs from a different org's context.
Related errors
- One or more collections could not be found.
- One or more collections are already governed by another acce
- A rule with that name already exists.
- Failed to remove organization vault. Please contact support.
- Organization must have at least one confirmed owner.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/326de6ce6b9e5393.
Report an issue: GitHub.