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

  1. Ensure the route template includes {orgId:guid} or {organizationId:guid}.
  2. Verify the client sends a valid GUID in the org ID route segment.
  3. Confirm the [InjectOrganizationUser] usage is paired with a route that has the org ID parameter.
  4. 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

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


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