siyuan-note/siyuan · warning
execute template [%s] failed: %s
Error message
execute template [%s] failed: %s
What it means
Thrown by evalRollupTemplate when text/template parsed the string successfully but Execute failed against the data context. Execution failures are runtime: wrong argument types/counts to a sprig function, indexing into a missing key, or calling a removed function. The error is surfaced to the user as a 30-second toast via pushRollupTemplateErr (calc_template.go:178).
Source
Thrown at kernel/av/calc_template.go:98
// evalRollupTemplate 使用 text/template + sprig 渲染自定义模板统计内容。
// 返回渲染后的字符串;若该字符串可解析为数字则 isNumber 为 true 且 asNumber 为该数值。
// 解析或执行失败时返回 err,由调用方决定如何提示用户。
func evalRollupTemplate(templateContent string, ctx map[string]any) (rendered string, asNumber float64, isNumber bool, err error) {
if "" == templateContent {
return
}
goTpl := template.New("").Delims(".action{", "}").Funcs(templateFuncMap())
tpl, parseErr := goTpl.Parse(templateContent)
if nil != parseErr {
err = fmt.Errorf("parse template [%s] failed: %s", templateContent, parseErr)
return
}
buf := &bytes.Buffer{}
if execErr := tpl.Execute(buf, ctx); nil != execErr {
err = fmt.Errorf("execute template [%s] failed: %s", templateContent, execErr)
return
}
rendered = buf.String()
if "<no value>" == rendered {
rendered = ""
return
}
// 渲染结果若可解析为数字,则按数字处理(前端会按列数字格式显示)
trimmed := strings.TrimSpace(rendered)
if "" != trimmed {
if num, parseErr := strconv.ParseFloat(trimmed, 64); nil == parseErr {
asNumber = num
isNumber = true
}
}
returnView on GitHub (pinned to 251596fc0d)
Solutions
- Use only the documented context keys: values, strings, raw, count, sum, avg, min, max, median, nonEmptyCount (buildRollupTemplateContext, calc_template.go:35-78).
- Avoid env, expandenv, getHostByName — they were removed; use static values instead.
- Test arithmetic expressions in isolation (e.g. .action{ add .sum 1 }) to confirm sprig function signatures.
Example fix
// before
calc.Template = ".action{ .average }"
// after
calc.Template = ".action{ .avg }" Defensive patterns
Strategy: try-catch
Try / catch
// Execution errors are runtime; catch them at the calc site and degrade gracefully.
rendered, asNumber, isNumber, err := evalRollupTemplate(calc.Template, ctx)
if err != nil {
pushRollupTemplateErr(err) // toast + leave calc.Result empty
return
}
// use rendered / asNumber / isNumber Prevention
- Keep a whitelist of context keys you reference (sum/avg/min/max/median/count/nonEmptyCount/values/strings/raw).
- Avoid env/expandenv/getHostByName — they are removed for security (GHSA-v97v-gxxg-rhmq).
- Add a dry-run render in the UI with sample data so users see execution errors before saving.
When it happens
Trigger: Template references a context key that does not exist (e.g. .average instead of .avg), invokes a sprig function with the wrong arity, or calls env/expandenv/getHostByName which were deleted for security. Fires during column calc rendering in calc.go:2003 and calcFieldByTemplate in calc_template.go:164.
Common situations: Misremembering the exposed context keys; copy-pasting a sprig recipe that needs args differently; version skew after the security removal of env-like funcs (GHSA-v97v-gxxg-rhmq).
Related errors
- parse template [%s] failed: %s
- Parse template failed: %s
- encrypted notebook is locked, please unlock it first
- new item templates config is nil
- clone new item template failed
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/145b092dd49d3370.
Report an issue: GitHub.