weaviate/weaviate · warning
roles can not be empty
Error message
roles can not be empty
What it means
A 400 Bad Request returned when the assign-roles request body contains an empty Roles array (len == 0). The handler checks this after namespace/user-type validation but before authorization and role resolution. Assigning zero roles is considered a malformed request rather than a no-op.
Source
Thrown at adapters/handlers/rest/authz/handlers_authz.go:812
if strings.TrimSpace(role) == "" {
return authz.NewAssignRoleToUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("one or more of the roles you want to assign is empty")))
}
if err := validateEnvVarRoles(role); err != nil {
return authz.NewAssignRoleToUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("assigning: %w", err)))
}
}
if err := h.validateUserIDForNamespaces(internalID); err != nil {
return authz.NewAssignRoleToUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
if err := h.validateUserTypeForNamespaces(params.Body.UserType); err != nil {
return authz.NewAssignRoleToUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
if len(params.Body.Roles) == 0 {
return authz.NewAssignRoleToUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("roles can not be empty")))
}
if err := h.authorizer.Authorize(ctx, principal, authorization.USER_AND_GROUP_ASSIGN_AND_REVOKE, authorization.Users(internalID)...); err != nil {
return authz.NewAssignRoleToUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
roleNames, notFound, err := h.resolveAssignableRoles(principal, params.Body.Roles)
if notFound {
return authz.NewAssignRoleToUserNotFound().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("one or more of the roles requested doesn't exist")))
}
if err != nil {
return authz.NewAssignRoleToUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
if err := h.validateLocalRoleAssignment(principal, roleNames); err != nil {
return authz.NewAssignRoleToUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Ensure the roles array has at least one non-empty role name before calling the API
- If the intent is to remove all roles, use the revoke-roles endpoint instead of assigning an empty list
- Add a client-side guard that skips the call when the roles list is empty
Example fix
// before
if len(roles) == 0 { roles = []string{} }
client.Users().Assigner().WithUser(id).WithRoles(roles...).Do(ctx)
// after
if len(roles) == 0 {
return nil // or use the revoke endpoint; do not call assign with empty list
}
client.Users().Assigner().WithUser(id).WithRoles(roles...).Do(ctx) Defensive patterns
Strategy: validation
Validate before calling
if len(roles) == 0 {
return errors.New("refusing to assign empty roles list; use revoke endpoint to remove roles")
} Prevention
- Guard the call site: skip assignment entirely when the roles slice is empty
- Use the revoke endpoint (POST /v1/users/{id}/roles/revoke) to remove roles, never assign-with-empty
- Filter invalid roles before assignment and abort if nothing remains
When it happens
Trigger: POST /v1/users/{userId}/roles/assign with body {"roles": []} (or roles omitted/null) and a valid UserType — the empty list check at handlers_authz.go:812 fires.
Common situations: Clients serializing an empty Go/JS slice into the request body; frontend that sends the assign call even when no checkboxes are selected; code paths that build the roles list dynamically and end up empty (e.g. after filtering out invalid roles).
Related errors
- one or more of the roles you want to assign is empty
- role name is required
- role name is invalid
- role name uses a reserved operator prefix
- permission is required
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/fb12cb25d83978af.
Report an issue: GitHub.