bitwarden/server · error · BadRequestException
Route parameter 'orgId' or 'organizationId' is missing or in
Error message
Route parameter 'orgId' or 'organizationId' is missing or invalid.
What it means
A BadRequestException (HTTP 400) thrown by OrganizationUserModelBinder when the orgId/organizationId route parameter is missing or not a valid GUID, during model binding for an [InjectOrganizationUser] parameter. Identical mechanism to the BindOrganization binder — GetOrganizationId() throws InvalidOperationException which is caught and converted to BadRequestException.
Source
Thrown at src/Api/AdminConsole/Attributes/InjectOrganizationUserAttribute.cs:67
/// </remarks>
public class OrganizationUserModelBinder : IModelBinder
{
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
var defaultMetadata = bindingContext.ModelMetadata as DefaultModelMetadata;
var attr = defaultMetadata?.Attributes.ParameterAttributes
?.OfType<InjectOrganizationUserAttribute>()
.FirstOrDefault()
?? new InjectOrganizationUserAttribute();
Guid orgId;
try
{
orgId = bindingContext.HttpContext.GetOrganizationId();
}
catch (InvalidOperationException)
{
throw new BadRequestException("Route parameter 'orgId' or 'organizationId' is missing or invalid.");
}
var orgUserId = bindingContext.HttpContext.TryGetRouteParameterAsGuid(attr.OrganizationUserIdRouteParam);
if (orgUserId is null)
{
throw new BadRequestException(
$"Route parameter '{attr.OrganizationUserIdRouteParam}' is missing or invalid.");
}
var repo = bindingContext.HttpContext.RequestServices
.GetRequiredService<IOrganizationUserRepository>();
var organizationUser = await repo.GetByIdAsync(orgUserId.Value);
if (organizationUser is null || organizationUser.OrganizationId != orgId)
{
throw new NotFoundException();
}
View on GitHub (pinned to e93b962371)
Solutions
- Ensure the route template includes {orgId:guid} or {organizationId:guid}.
- Verify the client sends a valid GUID in the org ID route segment.
- Confirm the [InjectOrganizationUser] usage is paired with a route that has the org ID parameter.
- Check for route conflicts that might match a different template without the org ID.
Example fix
// before: route missing orgId
[HttpPut("{id}/recover")]
public Task<IResult> Recover(Guid id, [InjectOrganizationUser] OrganizationUser user) { ... }
// after
[HttpPut("{orgId:guid}/{id}/recover")]
public Task<IResult> Recover(Guid orgId, Guid id, [InjectOrganizationUser] OrganizationUser user) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Ensure the route has orgId before calling an [InjectOrganizationUser] endpoint
if (!HttpContext.TryGetRouteParameterAsGuid("orgId").HasValue
&& !HttpContext.TryGetRouteParameterAsGuid("organizationId").HasValue)
{
return Results.BadRequest("orgId or organizationId route parameter is required.");
} Type guard
static bool HasOrgIdRoute(HttpContext ctx)
=> ctx.GetRouteData().Values.ContainsKey("orgId")
|| ctx.GetRouteData().Values.ContainsKey("organizationId"); Try / catch
try { /* action with [InjectOrganizationUser] */ }
catch (BadRequestException ex) when (ex.Message.Contains("orgId"))
{ return Results.BadRequest(ex.Message); } Prevention
- Pair [InjectOrganizationUser] with route templates that always include {orgId:guid}.
- Write route-convention tests asserting org-user endpoints carry an org ID segment.
- Review route templates after refactoring to catch missing segments.
When it happens
Trigger: A request to an endpoint with an [InjectOrganizationUser] parameter where the route lacks {orgId}/{organizationId} or the value is malformed. This binder also needs the org ID to validate that the org user belongs to the correct organization.
Common situations: Route template was changed during refactoring and no longer includes the org ID segment. Client sends a request with a non-GUID org ID. The controller action was moved to a different route without updating the template.
Related errors
- Route parameter 'orgId' or 'organizationId' is missing or in
- Route parameter '{attr.OrganizationUserIdRouteParam}' is mis
- Requested collections must belong to the same organization.
- Please provide an email and device identifier
- ExternalId cannot exceed 300 characters.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/5b3910a0b130f598.
Report an issue: GitHub.