siyuan-note/siyuan · error
attribute view [%s] has no available view: %w
Error message
attribute view [%s] has no available view: %w
What it means
When a template database node has no explicit view IAL, validateTemplateAttributeViewNode falls back to attrView.GetFirstView(). If that fails — the attribute view has no views at all — this wrapped error reports the attribute view ID with the underlying cause via %w.
Source
Thrown at kernel/model/template.go:498
if "" == value {
return TemplateDatabaseModeCopy, nil
}
ret = TemplateDatabaseMode(value)
if TemplateDatabaseModeCopy != ret && TemplateDatabaseModeReference != ret {
return "", fmt.Errorf("unsupported template database mode [%s]", value)
}
return
}
func validateTemplateAttributeViewNode(node *ast.Node, attrView *av.AttributeView) (selectedView *av.View, err error) {
viewID := strings.TrimSpace(node.IALAttr(av.NodeAttrView))
if "" != viewID {
selectedView = attrView.GetView(viewID)
if nil == selectedView {
return nil, fmt.Errorf("attribute view [%s] view [%s] not found", attrView.ID, viewID)
}
} else if selectedView, err = attrView.GetFirstView(); nil != err {
return nil, fmt.Errorf("attribute view [%s] has no available view: %w", attrView.ID, err)
}
visibleViewIDs := strings.TrimSpace(node.IALAttr(av.NodeAttrVisibleViewIDs))
if "" == visibleViewIDs {
return
}
visibleViewCount := 0
for _, visibleViewID := range strings.Split(visibleViewIDs, ",") {
visibleViewID = strings.TrimSpace(visibleViewID)
if "" == visibleViewID {
continue
}
visibleViewCount++
if nil == attrView.GetView(visibleViewID) {
return nil, fmt.Errorf("attribute view [%s] visible view [%s] not found", attrView.ID, visibleViewID)
}
}
if 1 > visibleViewCount {View on GitHub (pinned to 8641553a1f)
Solutions
- Open the source document and confirm the database still has at least one view; recreate one if it was deleted
- Remove the broken database block from the template
- Restore the database from snapshot/history or a sync backup
Defensive patterns
Strategy: validation
Validate before calling
if views := attrView.Views; len(views) == 0 {
return errors.New('attribute view has no views') // strip or skip this node before template use
} Type guard
func hasAnyView(attrView *av.AttributeView) bool {
_, err := attrView.GetFirstView()
return err == nil
} Try / catch
selectedView, err := validateTemplateAttributeViewNode(node, attrView)
if err != nil {
if strings.Contains(err.Error(), 'has no available view') {
return fmt.Errorf('skipping empty database %s', attrView.ID)
}
return err
} Prevention
- Never ship templates with databases that have zero views
- Verify databases after restoring from sync or history before saving as a template
- Add at least one view to any database included in a template
When it happens
Trigger: A template contains a database block whose attribute view exists but contains zero views, or GetFirstView returns an error because the view list is empty or corrupt.
Common situations: Hand-crafted templates with an empty av JSON, databases corrupted by failed sync, or templates referencing a deleted database.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- attribute view [%s] view [%s] not found
- attribute view [%s] visible view [%s] not found
- attribute view [%s] has no available visible view
- view not found
- key not found
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/b66109ed3ed2db89.
Report an issue: GitHub.