{"record":{"id":"8e22dea887bc61c3","repo":"siyuan-note/siyuan","slug":"restored-database-binding-s-is-missing","errorCode":null,"errorMessage":"restored database binding [%s] is missing","messagePattern":"restored database binding \\[(.+?)\\] is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_block_undo.go","lineNumber":127,"sourceCode":"\t\tif err := tx.rememberAttributeViewMutationTree(id); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tcurrent, err := tx.readAttributeViewForMutation(op.AvID, state.blockID, state.boxID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, src := range op.Srcs {\n\t\tid, _ := src[\"id\"].(string)\n\t\tif current.GetBlockValueByBoundID(id) != nil {\n\t\t\treturn fmt.Errorf(\"database binding [%s] already exists\", id)\n\t\t}\n\t\tnode, tree, err := getNodeByBlockID(tx, id)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif node == nil {\n\t\t\treturn fmt.Errorf(\"restored database binding [%s] is missing\", id)\n\t\t}\n\t\tif err = validateAttributeViewBinding(op.AvID, tree); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := tx.replayAttributeViewFields(op); err != nil {\n\t\treturn err\n\t}\n\trestored, err := tx.readAttributeViewForMutation(op.AvID, state.blockID, state.boxID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar itemIDs []string\n\tfor _, src := range op.Srcs {\n\t\tid, _ := src[\"id\"].(string)\n\t\tnode, tree, err := getNodeByBlockID(tx, id)\n\t\tif err != nil {\n\t\t\treturn err","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_block_undo.go#L109-L145","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Undo the block deletion first (or restore the document) so the block nodes exist, then undo the database-row deletion","Re-create blocks with the same IDs is generally impossible — instead roll back via document history (RollbackDocHistory), which handles missing snapshots gracefully","Skip/remove stale entries in the undo operation's Srcs whose blocks no longer exist, and re-create the rows manually","Refresh/re-open the documents to ensure the trees are loaded, then retry the undo"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: before undoing a row deletion, ensure the block still exists\nnode, tree, err := getNodeByBlockID(tx, blockID)\nblockExists := err == nil && node != nil","typeGuard":"if node == nil {\n    return ErrBlockMissing\n}","tryCatchPattern":"err := tx.restoreDeletedAttributeViewBlocks(op)\nif err != nil && strings.Contains(err.Error(), \"is missing\") {\n    // restore/undo the block deletion first, then retry\n}","preventionTips":["Always undo block deletions before undoing database-row deletions","Avoid deleting documents whose rows you plan to restore via undo","Use document history rollback when blocks are already gone","Keep undo operations atomic; do not clear undo stacks partially"],"tags":["database","undo","attribute-view","missing-block"],"backgroundTag":"record-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}