siyuan-note/siyuan · error

database history contains an invalid group

Error message

database history contains an invalid group

What it means

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.

Solutions

  1. Delete or replace the corrupt snapshot at <historyDir>/<boxID>/storage/av/<avID>.json and retry the rollback with an intact history version
  2. Edit the snapshot JSON to drop the null element from the view's groups array if it must be preserved
  3. Re-index / run workspace integrity checks to detect wider corruption
  4. Regenerate a fresh backup by re-deleting the document after confirming the live database views are valid
Defensive patterns

Strategy: validation

Validate before calling

// Go: check groups before group-level operations
for _, layout := range view.Views {
    for _, group := range layout.Groups {
        if group == nil {
            return errors.New("snapshot contains a nil group")
        }
    }
}

Type guard

if group == nil {
    continue
}

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "invalid group") {
        return ErrCorruptHistorySnapshot
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/1d083560e1eaaa8f. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_block_history.go:64

		if kv == nil || kv.Key == nil {
			return nil, errors.New("database history contains an invalid field")
		}
		for _, value := range kv.Values {
			if value == nil {
				return nil, errors.New("database history contains an invalid value")
			}
		}
	}
	if view.GetBlockKeyValues() == nil {
		return nil, errors.New("database history has no primary field")
	}
	for _, layout := range view.Views {
		if layout == nil {
			return nil, errors.New("database history contains an invalid view")
		}
		for _, group := range layout.Groups {
			if group == nil {
				return nil, errors.New("database history contains an invalid group")
			}
		}
	}
	return view, nil
}

// 内嵌数据库也先认证历史,并与绑定条目恢复一起纳入失败回滚。
func (tx *Transaction) restoreEmbeddedAttributeViewHistory(filename, boxID, avID string) error {
	historical, err := readBoundAttributeViewHistory(filename, boxID, avID)
	if err != nil {
		if boxID == "" && os.IsNotExist(err) {
			return nil
		}
		return err
	}
	current, err := tx.readAttributeViewForMutation(avID, "", boxID)
	if err != nil {
		return err

View on GitHub (pinned to 9f775e8a12)