siyuan-note/siyuan · error
database field [ ] changed since entries were deleted
Error message
database field [%s] changed since entries were deleted
What it means
validateAttributeViewItemKeys compares each key snapshot (taken when entries were removed or inserted) against the current database: the key must still exist with the same type and an identical Relation config (compared with reflect.DeepEqual). If the field was deleted, retyped, or its relation configuration changed, restoring the saved entries would write into a structurally different field, so the replay aborts.
Solutions
- Undo the column type/relation change so the field matches the snapshot before replaying entry operations
- Re-create a field with the same ID, type, and relation config if it was deleted
- Re-add the removed entries manually instead of replaying the old transaction
- When scripting schema changes, check for pending undo history on the database first and avoid interleaving type changes with row edits
Defensive patterns
Strategy: validation
Validate before calling
// compare current field type/relation against a saved snapshot before restoring entries
const cur = await getAttrView(avID);
for (const k of snapshotKeys) {
const now = cur.keyTypes[k.id];
if (!now || now.type !== k.type || JSON.stringify(now.relation) !== JSON.stringify(k.relation)) throw new Error(`field ${k.id} changed`);
} Try / catch
try { await restoreEntries(snapshot); } catch (e) { if (/changed since entries were deleted/.test(e.message)) { await undoSchemaChange(); retryRestore(); } else throw e; } Prevention
- Finish entry add/remove replays before changing column types or relation wiring
- Capture fresh snapshots instead of reusing stale ones after schema edits
- Keep schema migrations and row edits in separate undo units
When it happens
Trigger: Replaying prepareAttributeViewItemRemoval or restoreAttributeViewItems after the captured fields were deleted, type-converted (e.g. text to number), or had their Relation (AvID/BackKeyID/IsTwoWay) reconfigured since the snapshot was taken.
Common situations: Undoing an entry removal after later editing the column type or relation wiring; a plugin renamed/retyped columns via API between operations; sync merged a schema change into the database.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- database entry binding
- database entry [ ] already exists
- database field [ ] changed since document deletion
- attribute view not found
- cannot remove primary key field
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/2f59f14adb930a35.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_items.go:420
attrs[av.NodeAttrNameAvs] = strings.Trim(strings.Join(ids, ","), ",")
attrs[av.NodeAttrViewNames] = getAvNames(attrs[av.NodeAttrNameAvs])
if err = setNodeAttrsWithTx(tx, node, tree, attrs); err != nil {
return err
}
}
refreshRelatedSrcAvsInBlock(state.AvID, state.BlockID, tx)
if err = tx.replayAttributeViewItemConfiguration(state, true); err != nil {
return err
}
op.RetData = &insertAttrViewBlockResult{InsertedItemIDs: append([]string(nil), state.ItemIDs...)}
return nil
}
func validateAttributeViewItemKeys(current *av.AttributeView, state *attributeViewItemsSnapshot) error {
for _, kv := range state.Keys {
key, err := current.GetKey(kv.Key.ID)
if err != nil || key.Type != kv.Key.Type || !reflect.DeepEqual(key.Relation, kv.Key.Relation) {
return fmt.Errorf("database field [%s] changed since entries were deleted", kv.Key.ID)
}
}
return nil
}
func restoreAttributeViewItemOrder(current, original, itemIDs []string) []string {
for index, id := range original {
if !slices.Contains(itemIDs, id) || slices.Contains(current, id) {
continue
}
position := -1
for previous := index - 1; previous >= 0; previous-- {
if found := slices.Index(current, original[previous]); found >= 0 {
position = found + 1
break
}
}
if position < 0 {View on GitHub (pinned to 9f775e8a12)