{"record":{"id":"cdfc7c0c32ccee0a","repo":"siyuan-note/siyuan","slug":"conf-language-44","errorCode":null,"errorMessage":"Conf.Language(44)","messagePattern":"Conf\\.Language\\(44\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template.go","lineNumber":85,"sourceCode":"\n// RenderGoTemplateAt 使用固定时间渲染 Go 模板，保证同一次业务操作中的多个模板结果一致。\nfunc RenderGoTemplateAt(templateContent string, now time.Time) (ret string, err error) {\n\treturn RenderGoTemplateAtInBox(templateContent, now, \"\")\n}\n\nfunc RenderGoTemplateInBox(templateContent, boxID string) (ret string, err error) {\n\treturn RenderGoTemplateAtInBox(templateContent, time.Now(), boxID)\n}\n\nfunc RenderGoTemplateAtInBox(templateContent string, now time.Time, boxID string) (ret string, err error) {\n\ttmpl := template.New(\"\")\n\ttplFuncMap := filesys.BuiltInTemplateFuncs()\n\ttplFuncMap[\"now\"] = func() time.Time { return now }\n\tsql.SQLTemplateFuncs(&tplFuncMap, boxID)\n\ttmpl = tmpl.Funcs(tplFuncMap)\n\ttpl, err := tmpl.Parse(templateContent)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(Conf.Language(44), err.Error())\n\t}\n\n\tbuf := &bytes.Buffer{}\n\tbuf.Grow(4096)\n\terr = tpl.Execute(buf, nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(Conf.Language(44), err.Error())\n\t}\n\tret = buf.String()\n\treturn\n}\n\n// RemoveTemplate 删除模板文件，路径必须限定在 <data>/templates/ 目录内，防止任意文件被删除\nfunc RemoveTemplate(p string) (err error) {\n\tabs := p\n\tif !filepath.IsAbs(abs) {\n\t\tabs = filepath.Join(util.DataDir, \"templates\", p)\n\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template.go#L67-L103","documentation":"RenderGoTemplateAtInBox parses the given template content as a Go text/template with SiYuan's built-in and SQL template functions; a syntax error in Parse causes it to return the localized message Conf.Language(44) (template parse failed) wrapping the Go parser's error text. This is a template-authoring error, not a runtime/data error.","triggerScenarios":"Calling RenderGoTemplate / RenderGoTemplateAt / RenderGoTemplateInBox / RenderGoTemplateAtInBox (directly or via attribute-view item template resolution such as resolveAttributeViewNewItemTemplateWithFallback / resolveAttributeViewItemDocument) with templateContent containing invalid Go template syntax — unbalanced {{ }}, unknown functions at parse position, malformed pipelines.","commonSituations":"Hand-written templates with a typo like {{.Title} instead of {{.Title}}; using a function not registered in tplFuncMap or sql.SQLTemplateFuncs; templates copied from Markdown engines with different syntax (e.g. Handlebars); unclosed {{if}}/{{range}} blocks.","solutions":["Read the wrapped Go parser error in the message — it names the line/offset of the syntax problem — and fix the template text accordingly","Verify every {{...}} action is closed and every called function exists in SiYuan's template function set (filesys.BuiltInTemplateFuncs / sql.SQLTemplateFuncs)","Test the template with a minimal RenderGoTemplate call before using it in an attribute view or document template","Balance all {{if}}/{{range}}/{{with}} blocks with matching {{end}}"],"exampleFix":"// before: malformed action (missing closing braces)\ntemplateContent := \"Hello {{.title\"\n// after: well-formed action\ntemplateContent := \"Hello {{.title}}\"","handlingStrategy":"try-catch","validationCode":"function validateTemplateSyntax(tpl) {\n  // quick structural check before sending to the kernel\n  const opens = (tpl.match(/\\{\\{/g) || []).length;\n  const closes = (tpl.match(/\\}\\}/g) || []).length;\n  if (opens !== closes) throw new Error(\"unbalanced {{ }} in template\");\n  if (/\\{\\{[^}]*$/.test(tpl)) throw new Error(\"unclosed template action\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const html = await fetchPost(\"/api/template/render\", { template: templateContent });\n} catch (e) {\n  // message wraps Conf.Language(44) with the Go parser error incl. line/column\n  const parseDetail = extractParserDetail(e.message);\n  showTemplateEditorError(parseDetail);\n}","preventionTips":["Validate Go template syntax in an editor/linter before saving templates","Close every {{if}}/{{range}}/{{with}} with {{end}}","Use only functions registered in SiYuan's template function set (docs list them)","Test new templates with a small render call before wiring them into attribute views or documents"],"tags":["template","go-template","parse-error","syntax"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}