siyuan-note/siyuan · warning
attribute view groups changed; retry the drag
Error message
attribute view groups changed; retry the drag
What it means
After the row-order check passes, applyAttributeViewRowOrder compares the number of groups in the submitted RowOrder payload with the live view's group count. A mismatch means the grouping changed since the drag was previewed (group field changed, groups added/removed), so the drag is rejected for retry.
Source
Thrown at kernel/model/attribute_view_row_sort.go:235
}
return ret
}
func applyAttributeViewRowOrder(attrView *av.AttributeView, view *av.View, data any) error {
encoded, err := gulu.JSON.MarshalJSON(data)
if nil != err {
return err
}
var change attributeViewRowOrderChange
if err = gulu.JSON.UnmarshalJSON(encoded, &change); nil != err {
return err
}
if nil == change.RowOrder || nil == change.Expected ||
!reflect.DeepEqual(getAttributeViewRowOrder(view), change.Expected) {
return errors.New("attribute view order changed; retry the drag")
}
if len(change.RowOrder.Groups) != len(view.Groups) {
return errors.New("attribute view groups changed; retry the drag")
}
for _, group := range view.Groups {
if _, ok := change.RowOrder.Groups[group.ID]; !ok {
return errors.New("attribute view group not found")
}
}
if nil != change.ValidateGroup && len(change.RowOrder.Sorts) > 0 {
// 预览之后字段值可能变化,提交时再次校验,不能悄悄接受冲突的落点。
copyView, copyErr := cloneAttributeViewRowSort(attrView)
if nil != copyErr {
return copyErr
}
candidate := copyView.GetView(view.ID)
setAttributeViewRowOrder(candidate, change.RowOrder)
collections, renderErr := renderAttributeViewRowSortCollections(copyView, candidate, false)
if nil != renderErr {
return renderErr
}View on GitHub (pinned to 8641553a1f)
Solutions
- Reload the view with its current groups, rebuild the drag payload, and retry
- Verify the group configuration (group field/settings) is unchanged before committing the drag
- If a group change is intended, cancel the pending drag and re-perform it on the new grouping
Example fix
// before payload.RowOrder.Groups = oldGroups applyAttributeViewRowOrder(tx, avID, viewID, encode(payload)) // after payload.RowOrder.Groups = currentGroups(view) // rebuilt from the live view applyAttributeViewRowOrder(tx, avID, viewID, encode(payload))
Defensive patterns
Strategy: validation
Validate before calling
if (payload.RowOrder.Groups.length !== getViewGroupCount(avID, viewID)) {
payload = rebuildRowOrderChange(avID, viewID);
} Try / catch
try {
await sortAttributeViewRow(avID, viewID, encodedChange);
} catch (e) {
if (String(e.msg).includes("groups changed")) {
await reloadAttributeView(avID);
// cancel or rebuild the drag against the new grouping
}
} Prevention
- Re-read group configuration immediately before commit
- Cancel in-flight drags when the group-by field changes
- Avoid concurrently editing grouping in multiple windows during a drag
When it happens
Trigger: Calling sortAttributeViewRow when the view's grouping was modified between drag preview and commit — user changed the group-by field, a tab re-grouped the view, or the payload was built from an outdated grouped view.
Common situations: Two windows grouped the same database differently; a plugin changed the group configuration mid-drag; the client replayed an old payload after the view was re-grouped.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- attribute view order changed; retry the drag
- attribute view group not found
- attribute view sort values changed; retry the drag
- no attribute view rows selected
- attribute view rows changed; retry the drag
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/35240382b3663575.
Report an issue: GitHub.