siyuan-note/siyuan · error
view [ ] not found in attribute view [ ]
Error message
view [%s] not found in attribute view [%s]
What it means
Every ID passed in viewIDs must reference an existing view in the attribute view; SetDatabaseBlockVisibleViews uses attrView.GetView(viewID) and rejects any unknown ID. This prevents writing stale or bogus view IDs into the block's visible-view attribute.
Solutions
- Fetch the current views (GetAttributeView / attrView.Views) and filter viewIDs to existing IDs before calling.
- If a view was deleted, remove its ID from the visible list instead of passing it.
- Re-read the attribute view after sync to refresh cached view IDs in the caller.
Example fix
// before setVisibleViews(avID, cachedViewIds); // after const existing = new Set(attrView.views.map(v => v.id)); setVisibleViews(avID, cachedViewIds.filter(id => existing.has(id)));
Defensive patterns
Strategy: validation
Validate before calling
const existing = new Set(attrView.views.map(v => v.id));
const valid = viewIDs.filter(id => existing.has(id));
if (valid.length !== viewIDs.length) throw new Error('unknown view id in request'); Type guard
const viewExists = (av: { views: { id: string }[] }, id: string): boolean => av.views.some(v => v.id === id); Try / catch
try { await setVisibleViews(blockID, avID, viewIDs); } catch (e) { if (String(e).includes('not found in attribute view')) { await refreshAttrView(avID); } else throw e; } Prevention
- Derive view IDs from a freshly fetched attribute view, not from cache
- Purge cached view IDs when a view is deleted
- Distinguish view IDs from block IDs and field IDs
When it happens
Trigger: Calling SetDatabaseBlockVisibleViews with a viewIDs entry that was deleted, belongs to a different attribute view, or was never created (typo / stale ID).
Common situations: Plugin caches view IDs and one view was deleted meanwhile; frontend and kernel state diverged after a sync or concurrent edit; passing a block ID instead of a view ID by mistake.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- at least one visible view is required
- attribute view custom color index
- attribute view custom color must not be null
- attribute view custom colors count exceeds the
- attribute view custom colors must not be empty
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/1199b3e50a28852b.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:1398
}
return
}
func SetDatabaseBlockVisibleViews(blockID, avID string, viewIDs []string) (err error) {
if 1 > len(viewIDs) {
return errors.New("at least one visible view is required")
}
attrView, err := av.ParseAttributeView(avID)
if nil != err {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
visible := map[string]bool{}
for _, viewID := range viewIDs {
if nil == attrView.GetView(viewID) {
return fmt.Errorf("view [%s] not found in attribute view [%s]", viewID, avID)
}
visible[viewID] = true
}
var normalized []string
for _, view := range attrView.Views {
if visible[view.ID] {
normalized = append(normalized, view.ID)
}
}
if 1 > len(normalized) {
return errors.New("at least one visible view is required")
}
node, tree, err := getNodeByBlockID(nil, blockID)
if nil != err {
return
}View on GitHub (pinned to 9f775e8a12)