siyuan-note/siyuan · error
parse template tree failed
Error message
parse template tree failed
What it means
parseTemplateKTree could not produce a valid parse tree from the template markdown. The Lute parser (parse.Parse) returned nil, meaning the input could not be parsed into a tree, so a descriptive error is returned instead of a nil-tree panic downstream.
Source
Thrown at kernel/model/template_export_attrs.go:34
package model
import (
"bytes"
"errors"
"strings"
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
)
const templateDocumentAttributeMarker = "siyuan-template-doc-attrs-v1"
func parseTemplateKTree(markdown []byte) (*parse.Tree, error) {
engine := NewLute()
tree := parse.Parse("", markdown, engine.ParseOptions)
if tree == nil {
return nil, errors.New("parse template tree failed")
}
normalizeTree(tree)
if err := applyTemplateDocumentAttributes(tree); err != nil {
return nil, err
}
return tree, nil
}
// 独立文档属性保留在原位置求值,渲染完成后再合并到根节点。
func applyTemplateDocumentAttributes(tree *parse.Tree) error {
for node := tree.Root.FirstChild; node != nil; {
next := node.Next
info := node.ChildByType(ast.NodeCodeBlockFenceInfoMarker)
if node.Type == ast.NodeCodeBlock && info != nil && string(info.CodeBlockInfo) == templateDocumentAttributeMarker {
code := node.ChildByType(ast.NodeCodeBlockCode)
if code == nil {
return errors.New("invalid template document attributes")
}View on GitHub (pinned to 8641553a1f)
Solutions
- Check the template markdown file exists, is non-empty, and is valid UTF-8 before calling
- Verify the caller checked the read error before passing markdown bytes
- Re-save or recreate the corrupted template file
Example fix
// before
markdown, _ := os.ReadFile(p) // error ignored -> nil tree
tree, err := parseTemplateKTree(markdown)
// after
markdown, err := os.ReadFile(p)
if err != nil { return err }
tree, err := parseTemplateKTree(markdown)
Defensive patterns
Strategy: try-catch
Validate before calling
if len(markdown) == 0 || !utf8.Valid(markdown) { return errors.New("empty or non-UTF8 template markdown") } Type guard
func validTree(t *parse.Tree) bool { return t != nil && t.Root != nil } Try / catch
tree, err := parseTemplateKTree(markdown)
if err != nil {
log.Errorf("template parse failed: %v", err)
return fmt.Errorf("template is unparseable, re-save it: %w", err)
} Prevention
- Always check the file-read error before passing markdown bytes
- Validate templates are non-empty valid UTF-8 markdown
- Re-save corrupted templates instead of hand-patching bytes
When it happens
Trigger: parse.Parse("", markdown, engine.ParseOptions) returns nil inside parseTemplateKTree, called from renderTemplateSource, renderTemplateDocTreeMarkdown, or TestTemplateDocumentAttributeFormats when given malformed or empty/unparseable template markdown.
Common situations: Corrupted or truncated .md template files; a template containing bytes the parser cannot handle; passing nil/empty markdown due to an earlier failed file read whose error was ignored.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- parse tree [%s] failed
- 347
- Do not include Markdown syntax marker [%s]
- Do not include Markdown syntax marker [%s]
- Parse template failed: %s
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/67a849237dfa89cf.
Report an issue: GitHub.