siyuan-note/siyuan · error

attribute view [%s] view [%s] not found

Error message

attribute view [%s] view [%s] not found

What it means

validateTemplateAttributeViewNode checks that the attribute view referenced by a template node exists and that the view ID stored in the node view IAL attribute resolves. If the node names a viewID the attribute view does not contain (deleted or renamed view), this error names both the attribute view ID and the missing view ID.

Source

Thrown at kernel/model/template.go:495

func templateAttributeViewMode(node *ast.Node) (ret TemplateDatabaseMode, err error) {
	value := strings.TrimSpace(node.IALAttr(templateDatabaseModeAttr))
	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)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Re-save the template from a document whose database still contains the referenced view
  2. Edit the template and update or remove the view attribute on the database block so the first view is used
  3. Verify the attribute view ID exists and pick an existing view ID from it

Example fix

// before (database block IAL in template)
{: view='20240101120000-deleted-view'}
// after: omit view so the first view is selected
{: id='...'}
Defensive patterns

Strategy: validation

Validate before calling

viewID := strings.TrimSpace(node.IALAttr('view'))
if viewID != '' && attrView.GetView(viewID) == nil {
    node.RemoveIALAttr('view') // stale view; let the first view be used
}

Type guard

func hasView(attrView *av.AttributeView, viewID string) bool {
    return attrView.GetView(strings.TrimSpace(viewID)) != nil
}

Try / catch

selectedView, err := validateTemplateAttributeViewNode(node, attrView)
if err != nil {
    return fmt.Errorf('template database is stale: %w', err)
}

Prevention

When it happens

Trigger: Instantiating or saving a template whose database block has a view IAL (av.NodeAttrView) pointing to a view ID that was deleted or no longer exists in the source database.

Common situations: Templates exported before a view was deleted in the database, hand-edited templates copying a view ID from another attribute view, or template packs produced from an older document structure.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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