siyuan-note/siyuan · error
attribute view history context is ambiguous [%s]
Error message
attribute view history context is ambiguous [%s]
What it means
Thrown by ResolveHistoryAttributeViewBoxID when resolving which encrypted notebook owns a historical attribute view. After globbing history directories whose name starts with the formatted 'created' timestamp and scanning each for a file storage/av/<avID>.json (both at the global level and inside each notebook subdirectory), more than one distinct source context matched. The resolver requires exactly one match so it can decide whether an encrypted box key is needed.
Source
Thrown at kernel/model/attribute_view_render.go:1103
if gulu.File.IsExist(filepath.Join(historyDir, "storage", "av", avID+".json")) {
boxIDs = append(boxIDs, "")
}
entries, _ := os.ReadDir(historyDir)
for _, entry := range entries {
if !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {
continue
}
candidate := filepath.Join(historyDir, entry.Name(), "storage", "av", avID+".json")
if gulu.File.IsExist(candidate) {
boxIDs = append(boxIDs, entry.Name())
}
}
}
if len(boxIDs) == 0 {
return "", av.ErrAttributeViewNotFound
}
if len(boxIDs) != 1 {
return "", fmt.Errorf("attribute view history context is ambiguous [%s]", avID)
}
if IsEncryptedBox(boxIDs[0]) {
return boxIDs[0], nil
}
return "", nil
}
func RenderRepoSnapshotAttributeView(indexID, avID, viewID, carrierViewID string) (viewable av.Viewable, attrView *av.AttributeView, err error) {
if !ast.IsNodeIDPattern(avID) {
err = ErrInvalidID
return
}
repo, err := newRepository()
if err != nil {
return
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Inspect the matched history directory (named <created>-*) and delete or deduplicate the stray storage/av/<avID>.json so only one owner remains.
- If the duplicate is legitimate (e.g. two notebooks legitimately referencing one AV), restructure so the AV lives in exactly one storage location and the other references point to it.
- Regenerate the history snapshot after deduplication so the resolve path finds a single candidate.
Defensive patterns
Strategy: validation
Validate before calling
// Before rendering, ensure the AV resolves to exactly one history source.
boxID, err := model.ResolveHistoryAttributeViewBoxID(avID, created)
if err != nil {
// surface 'ambiguous' / 'not found' to the user; do not call render
return err
}
// boxID is "" for global plaintext or a boxID for encrypted; safe to proceed Try / catch
if err := model.ResolveHistoryAttributeViewBoxID(avID, created); err != nil {
if strings.Contains(err.Error(), "ambiguous") {
// prompt user to deduplicate the AV across notebooks/global storage
}
return err
} Prevention
- Keep each attribute view in exactly one storage location (global or a single notebook) to avoid ambiguous resolution.
- After sync/import, verify no AV ID appears under two paths in the same history snapshot.
- Treat an 'ambiguous' result as a data-integrity signal and dedupe before retrying.
When it happens
Trigger: Calling the history-attribute-view resolve/render flow (API renderHistoryAttributeView) with an avID that exists in more than one place within the matching history snapshot: simultaneously in global storage/av/ and inside a notebook <boxID>/storage/av/, or inside two different notebook subdirectories. Duplicate or mirrored AV files in the history tree make the owner ambiguous.
Common situations: A synced or imported workspace where an attribute view was copied between the global storage and a notebook, or where two notebooks each hold a file with the same avID. History snapshots taken right after such a copy produce multiple candidates. AV IDs are expected globally unique; a collision usually indicates duplicated data.
Related errors
- encrypted attribute view snapshot is missing notebook contex
- encrypted attribute view snapshot has no matching notebook [
- encrypted notebook attribute view snapshot is plaintext [%s]
- check encrypted notebook history failed: %w
- 323
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/d1d2bab4eb6a46f2.
Report an issue: GitHub.