siyuan-note/siyuan · warning
attribute view [%s] changed while loading search info
Error message
attribute view [%s] changed while loading search info
What it means
Logged and returned by loadAttributeViewSearchInfoInBox when cache.SetAVSearchDataInBox returns false after successfully parsing the AV data — meaning the on-disk data version no longer matches the version captured at read time. The AV was concurrently modified/saved (bumping its version) between the read and the cache-write, so the parsed search info was discarded as stale. This is a warn-level race signal, not data corruption.
Source
Thrown at kernel/av/av.go:671
if avBoxID != "" {
if data, err = decryptAVDataLocked(avBoxID, avID, data); err != nil {
logging.LogErrorf("decrypt attribute view [%s] failed: %s", avJSONPath, err)
return
}
} else if util.IsCiphertext(data) {
return nil, nil
}
}
if ret, err = parseAttributeViewSearchInfo(data); err != nil {
logging.LogErrorf("unmarshal attribute view search info [%s] failed: %s", avID, err)
return nil, err
}
if cache.SetAVSearchDataInBox(avID, avBoxID, dataVersion, ret) {
return ret, nil
}
}
err = fmt.Errorf("attribute view [%s] changed while loading search info", avID)
logging.LogWarnf("%s", err)
return nil, err
}
func GetAttributeViewContent(avID string) (content string) {
if "" == avID {
return
}
attrView, err := ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
if nil == attrView {
return
}
return getAttributeViewContent0(attrView)View on GitHub (pinned to 251596fc0d)
Solutions
- Retry the search-info read; the next attempt will pick up the new version and cache it.
- Reduce concurrent writers on the same AV (serialize saves) if the warning is frequent.
- Treat as benign in logs unless it persists for the same avID indefinitely, which would indicate a stuck version bump.
Example fix
// before
info, err := av.GetAttributeViewSearchInfoInBox(avID, boxID)
// after: retry once on the stale-version race
info, err := av.GetAttributeViewSearchInfoInBox(avID, boxID)
if err != nil && strings.Contains(err.Error(), "changed while loading") {
info, err = av.GetAttributeViewSearchInfoInBox(avID, boxID)
} Defensive patterns
Strategy: retry
Try / catch
info, err := av.GetAttributeViewSearchInfoInBox(avID, boxID)
if err != nil && strings.Contains(err.Error(), "changed while loading") {
// AV was saved concurrently; one retry picks up the new version
info, err = av.GetAttributeViewSearchInfoInBox(avID, boxID)
} Prevention
- Serialize concurrent saves to the same AV to minimize version races.
- Treat the warning as benign in logs unless it persists for one avID indefinitely.
- Avoid issuing reads and writes to the same AV from multiple tabs simultaneously.
When it happens
Trigger: Concurrent API calls: one thread loads search info (reads AV JSON at version N) while another thread saves the same AV (bumping version to N+1). When the loader tries to cache, the version check fails. Happens under rapid edits, sync, or background re-indexing touching the same AV.
Common situations: Two browser tabs editing the same database; a sync pull landing while the user is filtering; batch operations iterating AVs while one is being saved; full-text re-index racing an interactive edit.
Related errors
- attribute view spec is too new
- attribute view not found
- invalid attribute view id
- invalid box id
- view not found
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/92ffbd2083cb5861.
Report an issue: GitHub.