siyuan-note/siyuan · error

unsupported hpath refresh version

Error message

unsupported hpath refresh version %d

What it means

The persisted hpath refresh task store has a version field; readHPathRefreshTasks only understands version 1. When the JSON store on disk was written with a different (newer or corrupt) version number, the loader fails closed instead of misinterpreting an unknown format.

Solutions

  1. Upgrade the kernel to the version that wrote the store (check the store's version value against the supported format)
  2. If the store is corrupt or disposable, delete the hpath refresh store file and let the kernel rebuild pending refresh tasks from the document tree
  3. Do not hand-edit the version field to 1 without validating the tasks — entries are re-validated after the version check
Defensive patterns

Strategy: validation

Validate before calling

const raw = JSON.parse(storeFile); if (raw && raw.version !== 1) { /* upgrade kernel or drop the store */ }

Try / catch

tasks, err := model.LoadHPathRefresh(); if err != nil && strings.Contains(err.Error(), "unsupported hpath refresh version") { // delete store file or upgrade binary }

Prevention

When it happens

Trigger: loadHPathRefreshLocked reads the hpath refresh store file whose "version" field is not 1 — typically after a downgrade from a newer kernel version that wrote a later format, or manual/manual-tool edits of the store.

Common situations: Running an older SiYuan kernel against a workspace written by a newer version; a corrupted store file where the version integer was clobbered; hand-edited store JSON.

Related errors


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

Appendix: source

Thrown at kernel/model/hpath_refresh.go:94

func readHPathRefreshTasks(p string) (map[string]*hpathRefreshTask, error) {
	tasks := map[string]*hpathRefreshTask{}
	data, err := os.ReadFile(p)
	if os.IsNotExist(err) {
		return tasks, nil
	}
	if err != nil {
		return nil, err
	}
	var store struct {
		Version int                 `json:"version"`
		Tasks   []hpathRefreshEntry `json:"tasks"`
	}
	if err = json.Unmarshal(data, &store); err != nil {
		return nil, err
	}
	if store.Version != 1 {
		return nil, fmt.Errorf("unsupported hpath refresh version %d", store.Version)
	}
	for _, entry := range store.Tasks {
		if entry.ID == "" || entry.Box == "" {
			return nil, errors.New("invalid hpath refresh entry")
		}
		if _, err = filesys.ValidateBoxRelativePath(entry.Box, entry.Path); err != nil {
			return nil, err
		}
		tasks[entry.Box+"/"+entry.ID] = &hpathRefreshTask{hpathRefreshEntry: entry, recover: true, limit: 256}
	}
	return tasks, nil
}

func saveHPathRefreshLocked() error {
	return writeHPathRefreshTasks(hpathRefresh.file, hpathRefresh.tasks)
}

func writeHPathRefreshTasks(p string, tasks map[string]*hpathRefreshTask) error {

View on GitHub (pinned to 9f775e8a12)