bitwarden/server · error · BadRequestException

Route parameter ' ' is missing or invalid.

Error message

Route parameter '{attr.OrganizationUserIdRouteParam}' is missing or invalid.

What it means

A BadRequestException (HTTP 400) thrown by OrganizationUserModelBinder when the organization-user ID route parameter (default 'id', configurable via the attribute constructor) is missing or cannot be parsed as a GUID. The binder uses TryGetRouteParameterAsGuid to read the param and throws if the result is null.

Solutions

  1. Ensure the route template includes the org user ID segment with the correct parameter name (default 'id').
  2. If the route uses a non-default name (e.g., 'organizationUserId'), pass it to the attribute: [InjectOrganizationUser("organizationUserId")].
  3. Verify the client sends a valid GUID in the correct URL segment.
  4. Check that the ID is not being sent as a query string or body field instead of a route value.

Example fix

// before: route uses 'organizationUserId' but attribute defaults to 'id'
[HttpPost("{organizationUserId:guid}/accept")]
public Task<IResult> Accept(Guid organizationUserId,
    [InjectOrganizationUser] OrganizationUser user) { ... }
// after: tell the binder which route param to read
[HttpPost("{organizationUserId:guid}/accept")]
public Task<IResult> Accept(Guid organizationUserId,
    [InjectOrganizationUser("organizationUserId")] OrganizationUser user) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the org user ID route param matches the attribute's expected name
var routeParamName = "id"; // must match [InjectOrganizationUser] constructor arg
if (!HttpContext.TryGetRouteParameterAsGuid(routeParamName).HasValue)
{
    return Results.BadRequest($"Route parameter '{routeParamName}' is missing or invalid.");
}

Type guard

static bool HasOrgUserIdRoute(HttpContext ctx, string paramName)
    => ctx.TryGetRouteParameterAsGuid(paramName).HasValue;

Try / catch

try { /* action with [InjectOrganizationUser] */ }
catch (BadRequestException ex) when (ex.Message.Contains("is missing or invalid"))
{ return Results.BadRequest(ex.Message); }

Prevention

When it happens

Trigger: A request to an [InjectOrganizationUser] endpoint where the route value for the org user ID parameter (named by OrganizationUserIdRouteParam, default 'id') is absent, empty, or not a GUID.

Common situations: The route template uses a different parameter name than the attribute expects (e.g., route has {organizationUserId} but the attribute was applied without specifying that name). A client omits the ID from the URL. The ID is passed as a query parameter instead of a route segment.

Related errors


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

Appendix: source

Thrown at src/Api/AdminConsole/Attributes/InjectOrganizationUserAttribute.cs:73

        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();
        }

        bindingContext.Result = ModelBindingResult.Success(organizationUser);
    }
}

View on GitHub (pinned to e93b962371)