{"record":{"id":"3e3558425ba5ad63","repo":"siyuan-note/siyuan","slug":"parse-template-failed-s","errorCode":null,"errorMessage":"Parse template failed: %s","messagePattern":"Parse template failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template.go","lineNumber":417,"sourceCode":"\t\tdataModel[\"id\"] = block.ID\n\t\tdataModel[\"name\"] = block.Name\n\t\tdataModel[\"alias\"] = block.Alias\n\t}\n\n\tgoTpl := template.New(\"\").Delims(\".action{\", \"}\")\n\ttplFuncMap := filesys.BuiltInTemplateFuncs()\n\tsql.SQLTemplateFuncs(&tplFuncMap, tree.Box)\n\tgoTpl = goTpl.Funcs(tplFuncMap)\n\ttpl, err := goTpl.Funcs(tplFuncMap).Parse(gulu.Str.FromBytes(md))\n\tif err != nil {\n\t\terr = fmt.Errorf(Conf.Language(44), err.Error())\n\t\treturn\n\t}\n\n\tbuf := &bytes.Buffer{}\n\tbuf.Grow(4096)\n\tif err = tpl.Execute(buf, dataModel); err != nil {\n\t\terr = fmt.Errorf(Conf.Language(44), err.Error())\n\t\treturn\n\t}\n\tmd = buf.Bytes()\n\ttree = parseKTree(md)\n\tif nil == tree {\n\t\tmsg := fmt.Sprintf(\"parse tree [%s] failed\", p)\n\t\tlogging.LogError(msg)\n\t\terr = errors.New(msg)\n\t\treturn\n\t}\n\n\tvar nodesNeedAppendChild, unlinks []*ast.Node\n\t// 模板内部块旧 ID 到新 ID 的映射，用于成套改写模板内部的自引用\n\tblockIDs := map[string]string{}\n\tast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {\n\t\tif !entering {\n\t\t\treturn ast.WalkContinue\n\t\t}","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/template.go#L399-L435","documentation":"Returned by RenderTemplate when the content template parses fine but fails to EXECUTE against dataModel (template.go:417). Message is Conf.Language(44). dataModel includes title/id/name/alias (and conditionally more). Execution errors come from runtime func failures, nil dereferences, or SQL func errors against the box database.","triggerScenarios":"A .action{} action calls a sql.* function that fails because the notebook is not indexed or the query is malformed; an action accesses a missing dataModel key; a built-in func receives wrong argument types that pass parse-time checks but fail at execution.","commonSituations":"Inserting a template that runs sql.* queries right after opening a notebook before indexing completes; a template referencing .action{.someKey} not in the model; a date/format func error on empty input.","solutions":["Read the wrapped inner error (%s) — it identifies the failing function or nil dereference.","For sql.* funcs, ensure the notebook (tree.Box) is fully indexed before inserting the template.","Limit field access to keys present in dataModel (title, id, name, alias, plus block-derived vars).","Use the 'default' template func to guard empty values."],"exampleFix":"// before — sql func fails on unindexed box\n.action{sql \"SELECT ...\"}\n\n// after — index box first, or guard output\n.action{sql \"SELECT ...\" | default \"(indexing)\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"tree, dom, err := model.RenderTemplate(p, id, preview)\nif err != nil {\n    if strings.Contains(err.Error(), Conf.Language(44)) {\n        // template execution failure; show the inner cause to the user\n    }\n    return handleTemplateError(err)\n}","preventionTips":["Ensure the target notebook is fully indexed before inserting templates that call sql.* funcs.","Keep field access limited to keys present in dataModel.","Guard empty values with the 'default' template func."],"tags":["template","go-template","runtime","i18n","sql"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}