siyuan-note/siyuan · error

database [ ]

Error message

database [%s]: %w

What it means

replayAttributeViewFields serializes the current database, applies the recorded JSON patch (state.changes[id].apply), and wraps any patch-application failure with 'database [<avID>]: <cause>'. This means the recorded before/after diff for that database can no longer be applied cleanly to the live JSON — the underlying document structure drifted from what was captured.

Solutions

  1. Re-sync or reload the workspace so the database matches the version the snapshot was taken from
  2. Drop the conflicting undo/redo entry and manually re-apply the intended field change
  3. Upgrade/downgrade consistently across all devices so the database JSON format matches what the kernel that recorded the patch expects

Example fix

// before
patched, _, err := state.changes[id].apply(data, true, undo)
if err != nil { panic(err) }
// after
patched, _, err := state.changes[id].apply(data, true, undo)
if err != nil {
    return fmt.Errorf("database [%s]: %w", id, err) // surfaced: refresh or skip replay
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := tx.replayAttributeViewFields(op); err != nil {
    var wrapped = err.Error()
    if strings.Contains(wrapped, "database [") {
    // patch no longer applies: log avID, refresh or skip the undo step
    return nil
}
return err

Prevention

When it happens

Trigger: Undo/redo replay of add/remove-column, update-column-options, restore-deleted-blocks, sort-item, or item-configuration operations when the live attribute-view JSON no longer matches the patch base (fields, views, filters, or values changed by sync, concurrent edits, or format upgrades).

Common situations: Workspace synced between versions with changed database JSON schema; the database was edited by another client while undo was pending; a plugin wrote the .av JSON directly bypassing transactions.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/9d4068f3f165306c. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_fields.go:271

			}
		}
		// 恢复双向定义时,另一端的单向值必须仍与删除时一致。
		for keyID, expected := range state.relationValues[id] {
			kv, keyErr := current.GetKeyValues(keyID)
			if keyErr != nil {
				return keyErr
			}
			if !reflect.DeepEqual(attributeViewRelationValueIDs(kv.Values), expected) {
				return fmt.Errorf("database back relation values [%s] changed after field deletion", keyID)
			}
		}
		data, err := attributeViewFieldJSON(current)
		if err != nil {
			return err
		}
		patched, _, err := state.changes[id].apply(data, true, op.attributeViewFieldUndo)
		if err != nil {
			return fmt.Errorf("database [%s]: %w", id, err)
		}
		encoded, err := json.Marshal(patched)
		if err != nil {
			return err
		}
		restored := &av.AttributeView{}
		if err = json.Unmarshal(encoded, restored); err != nil {
			return err
		}
		for _, kv := range restored.KeyValues {
			if _, keyErr := current.GetKey(kv.Key.ID); keyErr == nil {
				continue
			}
			for _, value := range kv.Values {
				if restored.GetBlockValue(value.BlockID) == nil {
					return fmt.Errorf("database entry [%s] was removed after the field", value.BlockID)
				}
			}

View on GitHub (pinned to 9f775e8a12)