{"record":{"id":"1d083560e1eaaa8f","repo":"siyuan-note/siyuan","slug":"database-history-contains-an-invalid-group","errorCode":null,"errorMessage":"database history contains an invalid group","messagePattern":"database history contains an invalid group","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_block_history.go","lineNumber":64,"sourceCode":"\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\n\t}\n\tcurrent, err := tx.readAttributeViewForMutation(avID, \"\", boxID)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_block_history.go#L46-L82","documentation":"After validating views, readBoundAttributeViewHistory iterates each view's Groups and rejects the snapshot if any group is nil. Groups organize rows within a view (e.g. by group-by field); a nil group means the historical layout data is incomplete. The kernel aborts the backup/merge so subsequent group handling (GetGroupByID, GroupItemIDs restoration) never operates on a null group.","triggerScenarios":"RollbackDocHistory (restoreBoundAttributeViewHistory), restoreEmbeddedAttributeViewHistory, or backupBoundAttributeViewHistory reads a historical storage/av/<avID>.json where a view's \"groups\" array contains a null element — corrupted, truncated, or hand-edited history data.","commonSituations":"Grouped database views whose history snapshot was damaged or partially written; snapshots edited manually where a group was nulled out instead of removed; older/foreign versions of history files with incompatible layout serialization.","solutions":["Delete or replace the corrupt snapshot at <historyDir>/<boxID>/storage/av/<avID>.json and retry the rollback with an intact history version","Edit the snapshot JSON to drop the null element from the view's groups array if it must be preserved","Re-index / run workspace integrity checks to detect wider corruption","Regenerate a fresh backup by re-deleting the document after confirming the live database views are valid"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: check groups before group-level operations\nfor _, layout := range view.Views {\n    for _, group := range layout.Groups {\n        if group == nil {\n            return errors.New(\"snapshot contains a nil group\")\n        }\n    }\n}","typeGuard":"if group == nil {\n    continue\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"invalid group\") {\n        return ErrCorruptHistorySnapshot\n    }\n    return err\n}","preventionTips":["Delete and regenerate corrupt snapshots instead of patching groups in place","Avoid third-party tools that rewrite attribute-view JSON","Run workspace integrity checks after crashes","Keep grouped views' snapshots tested via rollback drills"],"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"}