siyuan-note/siyuan · error

restored database entry

Error message

restored database entry [%s] is missing

What it means

During undo of a transaction that inserted attribute-view (database) blocks, restoreDeletedAttributeViewBlocks re-adds previously deleted rows into the attribute view and then validates that the specific item (row) being restored exists in the restored collection. If GetBlockValue(itemID) returns nil — i.e. no block value with that item ID exists after restore — it aborts the transaction with this error. This is an internal consistency guard: the undo log references a database row that the restore operation could not actually materialize.

Solutions

  1. Verify the target database still exists and the row with the given itemID is present before triggering undo
  2. Refresh/reload the document so the attribute-view index matches disk, then retry the undo
  3. Check for sync or concurrent-edit conflicts that removed the row and resolve conflicts first
  4. If reproducible, clear the undo stack for the affected document (re-open the document) and report the mismatch
Defensive patterns

Strategy: validation

Validate before calling

av := getAttributeView(avID)
item := av.GetBlockValue(itemID)
if item == nil || item.Block == nil { return fmt.Errorf("item %s no longer exists; undo unavailable", itemID) }

Type guard

func canUndoAttrViewBlock(av *av.AttributeView, itemID string) bool {
    v := av.GetBlockValue(itemID)
    return v != nil && v.Block != nil
}

Try / catch

if err := doUndo(tx); err != nil {
    if strings.Contains(err.Error(), "restored database entry") {
        refreshDocument(); return // undo stack stale, reload instead
    }
    return err
}

Prevention

When it happens

Trigger: Undoing a doInsertAttrViewBlock operation when the transaction's src.ID (itemID) does not match any row restored into the target attribute view; e.g. the database was modified, the row was permanently deleted, or the AV was unlinked between the original operation and the undo.

Common situations: Undo stack references stale data after the database table was deleted or re-created; concurrent edits removed the row; a corrupted or partially synced .sy file leaves the AV index without the expected item; undoing across a sync that replaced the document's databases.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/attribute_view_block_undo.go:150

	}
	if err := tx.replayAttributeViewFields(op); err != nil {
		return err
	}
	restored, err := tx.readAttributeViewForMutation(op.AvID, state.blockID, state.boxID)
	if err != nil {
		return err
	}
	var itemIDs []string
	for _, src := range op.Srcs {
		id, _ := src["id"].(string)
		node, tree, err := getNodeByBlockID(tx, id)
		if err != nil {
			return err
		}
		itemID, _ := src["itemID"].(string)
		primary := restored.GetBlockValue(itemID)
		if primary == nil || primary.Block == nil {
			return fmt.Errorf("restored database entry [%s] is missing", itemID)
		}
		attrs := parse.IAL2Map(node.KramdownIAL)
		ids := strings.Split(attrs[av.NodeAttrNameAvs], ",")
		if !slices.Contains(ids, op.AvID) {
			ids = append(ids, op.AvID)
		}
		attrs[av.NodeAttrNameAvs] = strings.Trim(strings.Join(ids, ","), ",")
		attrs[av.NodeAttrViewNames] = getAvNames(attrs[av.NodeAttrNameAvs])
		if primary.Block.RefSubtype == "s" {
			attrs[av.NodeAttrViewStaticText+"-"+op.AvID] = primary.Block.Content
		}
		if err = setNodeAttrsWithTx(tx, node, tree, attrs); err != nil {
			return err
		}
		itemIDs = append(itemIDs, itemID)
	}
	op.RetData = &insertAttrViewBlockResult{InsertedItemIDs: itemIDs}
	return nil

View on GitHub (pinned to 9f775e8a12)