bytebase/bytebase · error
no fields to update
Error message
no fields to update
What it means
UpdateRole in backend/store/role.go builds a SET clause from the Role patch fields (e.g. permissions). If none are set, set.Len() == 0 and the store returns "no fields to update" rather than issuing an UPDATE with an empty SET against the role table matched by resource_id and workspace.
Source
Thrown at backend/store/role.go:232
if v := patch.Name; v != nil {
set.Comma("name = ?", *v)
}
if v := patch.Description; v != nil {
set.Comma("description = ?", *v)
}
if v := patch.Permissions; v != nil {
p := &storepb.RolePermissions{}
for k := range *v {
p.Permissions = append(p.Permissions, k)
}
permissionBytes, err := protojson.Marshal(p)
if err != nil {
return nil, err
}
set.Comma("permissions = ?", permissionBytes)
}
if set.Len() == 0 {
return nil, errors.New("no fields to update")
}
q := qb.Q().Space(`
UPDATE role
SET ?
WHERE resource_id = ? AND workspace = ?
RETURNING name, description, permissions
`, set, patch.ResourceID, patch.Workspace)
query, args, err := q.ToSQL()
if err != nil {
return nil, errors.Wrapf(err, "failed to build sql")
}
role := &RoleMessage{
ResourceID: patch.ResourceID,
Permissions: map[permission.Permission]bool{},
}View on GitHub (pinned to 1870550677)
Solutions
- Set Permissions (or another patchable field) on the role update message before calling UpdateRole
- Validate in the API layer that the update mask covers at least one patchable field and return CodeInvalidArgument otherwise
- Skip the write and return the existing role when the request is a true no-op
Example fix
// before
_, err := store.UpdateRole(ctx, &store.RoleMessage{ResourceID: roleID, Workspace: ws})
// after
_, err := store.UpdateRole(ctx, &store.RoleMessage{ResourceID: roleID, Workspace: ws, Permissions: perms}) Defensive patterns
Strategy: validation
Validate before calling
if msg.Permissions == nil {
return connect.NewError(connect.CodeInvalidArgument, errors.New("role update requires permissions"))
} Try / catch
role, err := store.UpdateRole(ctx, msg)
if err != nil && strings.Contains(err.Error(), "no fields to update") {
return connect.NewError(connect.CodeInvalidArgument, errors.New("empty role update"))
} Prevention
- Populate the Permissions field for role updates
- Validate the update mask covers patchable fields in the service layer
- No-op saves should return the existing role without a write
When it happens
Trigger: Calling UpdateRole with a message lacking any patchable field — an API role update whose mask selects nothing, or a permissions update path where the permission list conversion failed before the set.Comma call.
Common situations: Client submits an empty role edit; an admin UI saves a form with no changes; handler filters masked fields and the mask contains only unsupported paths like title-only renames not backed by patch fields.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- no update field specified
- no update field provided
- no fields to update
- failed to get project
- failed to list instances
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/f255dba821c8ced7.
Report an issue: GitHub.