siyuan-note/siyuan · error

restored database binding

Error message

restored database binding [%s] is missing

What it means

As part of the undo for deleted attribute-view rows, each restored row must be re-bound to an existing document block. The code looks up the block by ID (getNodeByBlockID(tx, id)); if the node no longer exists in any open tree, the binding target is gone and the row cannot be re-attached, so the undo aborts naming the missing block ID.

Solutions

  1. Undo the block deletion first (or restore the document) so the block nodes exist, then undo the database-row deletion
  2. Re-create blocks with the same IDs is generally impossible — instead roll back via document history (RollbackDocHistory), which handles missing snapshots gracefully
  3. Skip/remove stale entries in the undo operation's Srcs whose blocks no longer exist, and re-create the rows manually
  4. Refresh/re-open the documents to ensure the trees are loaded, then retry the undo
Defensive patterns

Strategy: validation

Validate before calling

// Go: before undoing a row deletion, ensure the block still exists
node, tree, err := getNodeByBlockID(tx, blockID)
blockExists := err == nil && node != nil

Type guard

if node == nil {
    return ErrBlockMissing
}

Try / catch

err := tx.restoreDeletedAttributeViewBlocks(op)
if err != nil && strings.Contains(err.Error(), "is missing") {
    // restore/undo the block deletion first, then retry
}

Prevention

When it happens

Trigger: Undoing deletion of attribute-view rows whose bound document blocks were deleted (in the same or a later transaction) and are no longer available — e.g. the deletion of the blocks was not undone first, the block IDs are stale, or the document containing them was removed.

Common situations: Undoing only the database-row deletion while the block deletion itself is gone from the undo stack (partial undo); blocks deleted in a separate earlier transaction; document deleted and rolled back differently; IDs from an out-of-date undo operation after sync.

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/8e22dea887bc61c3. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_block_undo.go:127

		if err := tx.rememberAttributeViewMutationTree(id); err != nil {
			return err
		}
	}
	current, err := tx.readAttributeViewForMutation(op.AvID, state.blockID, state.boxID)
	if err != nil {
		return err
	}
	for _, src := range op.Srcs {
		id, _ := src["id"].(string)
		if current.GetBlockValueByBoundID(id) != nil {
			return fmt.Errorf("database binding [%s] already exists", id)
		}
		node, tree, err := getNodeByBlockID(tx, id)
		if err != nil {
			return err
		}
		if node == nil {
			return fmt.Errorf("restored database binding [%s] is missing", id)
		}
		if err = validateAttributeViewBinding(op.AvID, tree); err != nil {
			return err
		}
	}
	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

View on GitHub (pinned to 9f775e8a12)