{"record":{"id":"96fdeb8723665edb","repo":"siyuan-note/siyuan","slug":"database-history-contains-an-invalid-view","errorCode":null,"errorMessage":"database history contains an invalid view","messagePattern":"database history contains an invalid view","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_block_history.go","lineNumber":60,"sourceCode":"\tif view.ID != avID {\n\t\treturn nil, errors.New(\"database history ID does not match its filename\")\n\t}\n\tfor _, kv := range view.KeyValues {\n\t\tif kv == nil || kv.Key == nil {\n\t\t\treturn nil, errors.New(\"database history contains an invalid field\")\n\t\t}\n\t\tfor _, value := range kv.Values {\n\t\t\tif value == nil {\n\t\t\t\treturn nil, errors.New(\"database history contains an invalid value\")\n\t\t\t}\n\t\t}\n\t}\n\tif view.GetBlockKeyValues() == nil {\n\t\treturn nil, errors.New(\"database history has no primary field\")\n\t}\n\tfor _, layout := range view.Views {\n\t\tif layout == nil {\n\t\t\treturn nil, errors.New(\"database history contains an invalid view\")\n\t\t}\n\t\tfor _, group := range layout.Groups {\n\t\t\tif group == nil {\n\t\t\t\treturn nil, errors.New(\"database history contains an invalid group\")\n\t\t\t}\n\t\t}\n\t}\n\treturn view, nil\n}\n\n// 内嵌数据库也先认证历史，并与绑定条目恢复一起纳入失败回滚。\nfunc (tx *Transaction) restoreEmbeddedAttributeViewHistory(filename, boxID, avID string) error {\n\thistorical, err := readBoundAttributeViewHistory(filename, boxID, avID)\n\tif err != nil {\n\t\tif boxID == \"\" && os.IsNotExist(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_block_history.go#L42-L78","documentation":"readBoundAttributeViewHistory walks every entry in the snapshot's Views array and rejects the file if any layout/view is nil. A nil view means the historical attribute view data is structurally corrupt — a view slot exists in the slice but holds no object. The kernel aborts the backup or restore operation rather than operating on a partially dereferenced view list that would cause nil-pointer panics later.","triggerScenarios":"RollbackDocHistory (via restoreBoundAttributeViewHistory), restoreEmbeddedAttributeViewHistory, or backupBoundAttributeViewHistory loads a historical storage/av/<avID>.json whose parsed Views slice contains a null entry — typically from corrupted, hand-edited, or truncated JSON history files.","commonSituations":"History files corrupted by disk issues or interrupted writes; manually edited snapshots where a view was removed but left as null; snapshot files moved between workspaces with mismatched versions; failed sync producing partial history data.","solutions":["Remove or replace the malformed snapshot file at <historyDir>/<boxID>/storage/av/<avID>.json and choose another history version for the rollback","Open the snapshot JSON and remove the null entries from the \"views\" array (or restore a valid full copy) if you must keep it","Run data integrity checks / re-index the workspace to rule out broader corruption","If corruption recurs, check disk health and sync tooling; avoid editing history files in place"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: sanitize views before use\nfor _, layout := range view.Views {\n    if layout == nil {\n        return errors.New(\"snapshot contains a nil view\")\n    }\n}","typeGuard":"if layout == nil {\n    continue // or fail fast before dereferencing\n}","tryCatchPattern":"view, err := readBoundAttributeViewHistory(file, boxID, avID)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid view\") {\n        return ErrCorruptHistorySnapshot\n    }\n    return err\n}","preventionTips":["Avoid interrupting writes to history files (ensure clean shutdown/sync)","Do not edit snapshot JSON manually; delete and regenerate instead","Check disk health if history corruption recurs","Validate snapshots after restoring them from external backups"],"tags":["database","history","attribute-view","validation"],"backgroundTag":"schema-validation-failed","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"}