siyuan-note/siyuan · error
related database entry
Error message
related database entry [%s] is missing
What it means
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.
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
Defensive patterns
Strategy: validation
Validate before calling
// Go: verify relation targets exist before rollback
for _, targetID := range value.Relation.BlockIDs {
if dest.GetBlockValue(targetID) == nil {
// target row missing; restore it first or drop the link
}
} Type guard
if dest.GetBlockValue(targetID) == nil {
return ErrMissingRelatedEntry
} Try / catch
err := tx.restoreBoundAttributeViewHistory(tree, historyDir)
if err != nil && strings.Contains(err.Error(), "is missing") {
// restore the related document first, or clean the snapshot's relation value
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- database back relation changed since document deletion
- database back relation value is invalid
- database back relation field
- database back relation values
- database entry [ ] has a different binding
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/a84fae04e09bc953.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_block_history.go:233
if relation == nil || !relation.IsTwoWay {
continue
}
for _, value := range kv.Values {
if !slices.Contains(itemIDs, value.BlockID) || value.Relation == nil || len(value.Relation.BlockIDs) == 0 {
continue
}
dest, err := load(relation.AvID)
if err != nil {
return err
}
back, err := dest.GetKeyValues(relation.BackKeyID)
if err != nil || back.Key.Relation == nil || !back.Key.Relation.IsTwoWay ||
back.Key.Relation.AvID != id || back.Key.Relation.BackKeyID != kv.Key.ID {
return errors.New("database back relation changed since document deletion")
}
for _, targetID := range value.Relation.BlockIDs {
if dest.GetBlockValue(targetID) == nil {
return fmt.Errorf("related database entry [%s] is missing", targetID)
}
backValue := back.GetValue(targetID)
if backValue == nil {
backValue = &av.Value{ID: ast.NewNodeID(), KeyID: back.Key.ID, BlockID: targetID,
Type: av.KeyTypeRelation, Relation: &av.ValueRelation{}}
back.Values = append(back.Values, backValue)
}
if backValue.Relation == nil {
return errors.New("database back relation value is invalid")
}
if !slices.Contains(backValue.Relation.BlockIDs, value.BlockID) {
backValue.Relation.BlockIDs = append(backValue.Relation.BlockIDs, value.BlockID)
}
}
}
}
}
if len(restoredItems) == 0 {View on GitHub (pinned to 9f775e8a12)