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

  1. Open the source document and confirm the database still has at least one view; recreate one if it was deleted
  2. Remove the broken database block from the template
  3. 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

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


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/b66109ed3ed2db89. Report an issue: GitHub.