siyuan-note/siyuan · error

template definition [%s] not found

Error message

template definition [%s] not found

What it means

During the static call-graph walk, every referenced template name is resolved with root.Lookup. If a {{template "name"}} action references a define that does not exist in the template set (or has an empty AST), the walk fails with 'template definition [%s] not found'. This is essentially the same family as error 1543 but detected during call-graph validation rather than direct node rendering.

Source

Thrown at kernel/model/template_doc_tree_render.go:119

		return nil, fmt.Errorf(Conf.Language(44), err.Error())
	}
	return buf.Bytes(), nil
}

func validateTemplateCallGraph(root *template.Template, start string) error {
	visiting := map[string]bool{}
	depths := map[string]int{}
	var visit func(string) (int, error)
	visit = func(name string) (int, error) {
		if visiting[name] {
			return 0, fmt.Errorf("recursive template call [%s] is not supported", name)
		}
		if depth, ok := depths[name]; ok {
			return depth, nil
		}
		tmpl := root.Lookup(name)
		if nil == tmpl || nil == tmpl.Tree || nil == tmpl.Tree.Root {
			return 0, fmt.Errorf("template definition [%s] not found", name)
		}
		visiting[name] = true
		depth := 1
		for _, called := range collectCalledTemplateNames(tmpl.Tree.Root) {
			calledDepth, err := visit(called)
			if nil != err {
				return 0, err
			}
			if depth < calledDepth+1 {
				depth = calledDepth + 1
			}
		}
		delete(visiting, name)
		depths[name] = depth
		return depth, nil
	}
	depth, err := visit(start)
	if nil != err {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Define the missing template with {{define "name"}}...{{end}} in the same template set
  2. Fix the include name to match an existing define exactly (spelling/case)
  3. Ensure all files providing referenced defines are parsed into the same template set before validation
  4. Remove the stale {{template}} call if the referenced define is no longer needed

Example fix

// before
.action{template "header-v2"}
// after (define exists as "header")
.action{template "header"}
Defensive patterns

Strategy: validation

Validate before calling

for _, name := range referencedTemplateNames(tmplFiles) {
	if tmplSet.Lookup(name) == nil {
		return fmt.Errorf("referenced define %q missing from template set", name)
	}
}

Prevention

When it happens

Trigger: A define or child template file contains {{template "missingName"}} (or .action{template "missingName"}) where missingName was never defined via {{define}} in the same template set; an empty define block with no root node also triggers it.

Common situations: Typo in a template include name; include copied from another template package whose defines weren't loaded; conditional includes of names defined only in files that failed to load; renaming a define without updating callers.

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/c21fcbb42a002733. Report an issue: GitHub.