siyuan-note/siyuan · error

database history contains an invalid field

Error message

database history contains an invalid field

What it means

Structural validation of a parsed database history snapshot failed: a KeyValues entry or its Key is nil. The engine validates every history attribute view before use so restores never inject malformed fields into a live database; a nil key indicates a truncated or hand-edited history file.

Solutions

  1. Discard the corrupt history entry and choose another snapshot from the history list
  2. Restore the history file from backup
  3. Rebuild history by making a new change to the database to generate a fresh snapshot
  4. If corruption recurs, check storage integrity (disk, sync target) for the history directory
Defensive patterns

Strategy: validation

Validate before calling

function isValidHistoryView(view) {
  return view.keyValues.every(kv => kv && kv.key);
}

Type guard

const hasValidKeys = (view) =>
  Array.isArray(view.keyValues) && view.keyValues.every(kv => kv && kv.key);

Prevention

When it happens

Trigger: readBoundAttributeViewHistory iterating view.KeyValues where a kv pointer is nil or kv.Key is nil — produced by truncated/corrupt history files, partial writes, or files edited by external tools.

Common situations: Disk-full or interrupted writes when the snapshot was taken; merging history folders across workspaces; third-party scripts rewriting history JSON.

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/2a44507df85aea18. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_block_history.go:47

			return nil, errors.New("encrypted database history is plaintext")
		}
		data, err = av.DecryptAVData(boxID, avID, data)
		if err != nil {
			return nil, err
		}
	} else if util.IsCiphertext(data) {
		return nil, errors.New("encrypted database history has no notebook context")
	}
	view, err := av.ParseAttributeViewData(avID, data)
	if err != nil {
		return nil, err
	}
	if view.ID != avID {
		return nil, errors.New("database history ID does not match its filename")
	}
	for _, kv := range view.KeyValues {
		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")
			}

View on GitHub (pinned to 9f775e8a12)