{"record":{"id":"a84fae04e09bc953","repo":"siyuan-note/siyuan","slug":"related-database-entry-s-is-missing","errorCode":null,"errorMessage":"related database entry [%s] is missing","messagePattern":"related database entry \\[(.+?)\\] is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_block_history.go","lineNumber":233,"sourceCode":"\t\t\tif relation == nil || !relation.IsTwoWay {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, value := range kv.Values {\n\t\t\t\tif !slices.Contains(itemIDs, value.BlockID) || value.Relation == nil || len(value.Relation.BlockIDs) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tdest, err := load(relation.AvID)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tback, err := dest.GetKeyValues(relation.BackKeyID)\n\t\t\t\tif err != nil || back.Key.Relation == nil || !back.Key.Relation.IsTwoWay ||\n\t\t\t\t\tback.Key.Relation.AvID != id || back.Key.Relation.BackKeyID != kv.Key.ID {\n\t\t\t\t\treturn errors.New(\"database back relation changed since document deletion\")\n\t\t\t\t}\n\t\t\t\tfor _, targetID := range value.Relation.BlockIDs {\n\t\t\t\t\tif dest.GetBlockValue(targetID) == nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"related database entry [%s] is missing\", targetID)\n\t\t\t\t\t}\n\t\t\t\t\tbackValue := back.GetValue(targetID)\n\t\t\t\t\tif backValue == nil {\n\t\t\t\t\t\tbackValue = &av.Value{ID: ast.NewNodeID(), KeyID: back.Key.ID, BlockID: targetID,\n\t\t\t\t\t\t\tType: av.KeyTypeRelation, Relation: &av.ValueRelation{}}\n\t\t\t\t\t\tback.Values = append(back.Values, backValue)\n\t\t\t\t\t}\n\t\t\t\t\tif backValue.Relation == nil {\n\t\t\t\t\t\treturn errors.New(\"database back relation value is invalid\")\n\t\t\t\t\t}\n\t\t\t\t\tif !slices.Contains(backValue.Relation.BlockIDs, value.BlockID) {\n\t\t\t\t\t\tbackValue.Relation.BlockIDs = append(backValue.Relation.BlockIDs, value.BlockID)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif len(restoredItems) == 0 {","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_block_history.go#L215-L251","documentation":"When re-establishing a two-way relation for restored rows, each target block ID referenced by the historical relation value must exist as a row in the destination database (dest.GetBlockValue(targetID) != nil). If a referenced target row was itself deleted and cannot be found, the symmetric link would dangle, so the rollback aborts with the missing target ID.","triggerScenarios":"RollbackDocHistory where a restored row's two-way relation value references a row in another database that no longer exists — e.g. the related entry was deleted and its own document/database also cleaned up, or the target database's rows were purged between deletion and rollback.","commonSituations":"Cascading deletions where the related block/entry was removed too; rolling back only one of two interlinked documents; detached entries removed by other edits; snapshots referencing entries in databases that were since emptied.","solutions":["Restore the related document/entry first (roll back its history) so the target row exists, then roll back this document","Manually re-create the missing entry in the destination database with the target block ID, then retry","Remove the dangling relation value from the historical snapshot JSON so the restore can proceed without that link","Re-link the relation manually after the document rollback, deleting the offending history value"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: verify relation targets exist before rollback\nfor _, targetID := range value.Relation.BlockIDs {\n    if dest.GetBlockValue(targetID) == nil {\n        // target row missing; restore it first or drop the link\n    }\n}","typeGuard":"if dest.GetBlockValue(targetID) == nil {\n    return ErrMissingRelatedEntry\n}","tryCatchPattern":"err := tx.restoreBoundAttributeViewHistory(tree, historyDir)\nif err != nil && strings.Contains(err.Error(), \"is missing\") {\n    // restore the related document first, or clean the snapshot's relation value\n}","preventionTips":["Roll back interlinked documents together","Avoid deleting related entries while a rollback is pending","Clean dangling relation values in snapshots before merging","Keep relation targets within databases that share the same history policy"],"tags":["database","history","attribute-view","relation","missing-entry"],"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"}