{"record":{"id":"e3c107e772bb0992","repo":"thanos-io/thanos","slug":"failed-to-parse-template","errorCode":null,"errorMessage":"failed to parse template","messagePattern":"failed to parse template","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/thanos/rule.go","lineNumber":1130,"sourceCode":"\n\tmetrics.configSuccess.Set(1)\n\tmetrics.configSuccessTime.Set(float64(time.Now().UnixNano()) / 1e9)\n\n\tmetrics.rulesLoaded.Reset()\n\tfor _, group := range ruleMgr.RuleGroups() {\n\t\tmetrics.rulesLoaded.WithLabelValues(group.PartialResponseStrategy.String(), group.OriginalFile, group.Name()).Set(float64(len(group.Rules())))\n\t}\n\treturn errs.Err()\n}\n\nfunc tableLinkForExpression(tmpl string, expr string) (string, error) {\n\t// template example: \"/graph?g0.expr={{.Expr}}&g0.tab=1\"\n\tescapedExpression := url.QueryEscape(expr)\n\n\tescapedExpr := Expression{Expr: escapedExpression}\n\tt, err := texttemplate.New(\"url\").Parse(tmpl)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to parse template\")\n\t}\n\n\tvar buf bytes.Buffer\n\tif err := t.Execute(&buf, escapedExpr); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to execute template\")\n\t}\n\treturn buf.String(), nil\n}\n\nfunc validateTemplate(tmplStr string) error {\n\ttmpl, err := template.New(\"test\").Parse(tmplStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse the template: %w\", err)\n\t}\n\tvar buf bytes.Buffer\n\terr = tmpl.Execute(&buf, Expression{Expr: \"test_expr\"})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to execute the template: %w\", err)","sourceCodeStart":1112,"sourceCodeEnd":1148,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/cmd/thanos/rule.go#L1112-L1148","documentation":"In Thanos's rule UI URL templating (thanos rule, --alert.query-template style), the user-provided Go text/template used to build links like \"/graph?g0.expr={{.Expr}}\" is parsed with text/template. If the template string is not syntactically valid Go template syntax, errors.Wrap produces \"failed to parse template\" and URL generation aborts. The template is executed with an Expression struct exposing only the .Expr field (URL-query-escaped PromQL).","triggerScenarios":"Calling the URL-template function (invoked when generating external query links for alerts/rules) with a tmpl string containing malformed Go template syntax, e.g. unbalanced {{ }} braces, an unclosed action, or invalid pipeline syntax, causing texttemplate.New(\"url\").Parse(tmpl) to fail.","commonSituations":"Operators hand-write the URL template flag and typo the delimiters (e.g. \"/graph?g0.expr={{{.Expr}}}\" or a stray {{without an end}}); copying a Jinja2/Handlebars-style template instead of Go syntax; quoting issues in YAML/CLI mangle the braces.","solutions":["Check the template string for balanced, valid Go template actions: every {{ must have a matching }} and valid syntax (see https://pkg.go.dev/text/template).","Only reference fields that exist on the Expression data: use {{.Expr}} (the URL-escaped PromQL expression); other fields will fail at execute time, but syntax errors surface here.","Test the template offline with template.New(\"test\").Parse(tmpl) in a scratch Go program or rely thanos's own validateTemplate path before deploying.","If the flag comes from a YAML/Env config, verify shell/JSON escaping did not swallow or duplicate braces."],"exampleFix":"// before\ntmpl := \"/graph?g0.expr={{{.Expr}}}&g0.tab=1\"\n// after\ntmpl := \"/graph?g0.expr={{.Expr}}&g0.tab=1\"","handlingStrategy":"validation","validationCode":"func validTemplate(s string) bool {\n    _, err := texttemplate.New(\"check\").Parse(s)\n    return err == nil\n}\n// require validTemplate(tmpl) before passing to thanos rule flags","typeGuard":"null","tryCatchPattern":"if _, err := texttemplate.New(\"url\").Parse(tmpl); err != nil {\n    return fmt.Errorf(\"invalid url template %q: %w\", tmpl, err)\n}","preventionTips":["Keep templates to the minimal form \"/graph?g0.expr={{.Expr}}&g0.tab=1\" unless you have a tested reason otherwise","Run template validation (thanos's validateTemplate) in CI for any config that embeds Go templates","Beware of shell/YAML brace escaping when passing templates via flags or manifests"],"tags":["go","template","config","thanos"],"backgroundTag":"template-parse-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}