{"record":{"id":"ef549a29e21b6b1b","repo":"vxcontrol/pentagi","slug":"failed-to-parse-template-w","errorCode":null,"errorMessage":"failed to parse template: %w","messagePattern":"failed to parse template: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/templates/validator/validator.go","lineNumber":124,"sourceCode":"\n\t// Create function map with all builtin functions as nil values for the parser\n\tfuncMap := template.FuncMap{\n\t\t// Builtin comparison and logic functions\n\t\t\"and\": nil, \"or\": nil, \"not\": nil,\n\t\t\"eq\": nil, \"ne\": nil, \"lt\": nil, \"le\": nil, \"gt\": nil, \"ge\": nil,\n\t\t// Builtin utility functions\n\t\t\"len\": nil, \"index\": nil, \"slice\": nil, \"print\": nil, \"printf\": nil, \"println\": nil,\n\t\t\"html\": nil, \"js\": nil, \"urlquery\": nil, \"call\": nil,\n\t\t// Additional common functions that might be used\n\t\t\"add\": nil, \"sub\": nil, \"mul\": nil, \"div\": nil, \"mod\": nil,\n\t\t\"upper\": nil, \"lower\": nil, \"title\": nil, \"trim\": nil, \"trimSpace\": nil,\n\t\t\"default\": nil, \"empty\": nil, \"contains\": nil, \"hasPrefix\": nil, \"hasSuffix\": nil,\n\t}\n\n\t// Parse template with function map to get AST\n\tparsed, err := parse.Parse(\"validation\", templateContent, \"{{\", \"}}\", funcMap)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse template: %w\", err)\n\t}\n\n\tvariables := make(map[string]bool)\n\n\t// Analyze each tree in the template\n\tfor _, tree := range parsed {\n\t\tif tree != nil && tree.Root != nil {\n\t\t\textractVariablesFromNode(tree.Root, variables, false)\n\t\t}\n\t}\n\n\t// Convert to sorted slice for consistent comparison\n\tvar result []string\n\tfor varName := range variables {\n\t\tresult = append(result, varName)\n\t}\n\tsort.Strings(result)\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/templates/validator/validator.go#L106-L142","documentation":"ExtractTemplateVariables calls parse.Parse(\"validation\", content, \"{{\", \"}}\", funcMap) to build the template AST. Any syntax error Go's template parser reports (unclosed action, bad pipeline, unknown character) is wrapped with this message. The funcMap registers builtins as nil so parser-level references to them don't fail.","triggerScenarios":"Passing template text with malformed Go template syntax to ExtractTemplateVariables or ValidatePrompt: '{{ .Name' (missing close), '{{if}}' without '{{end}}', invalid function call syntax, stray '}}'.","commonSituations":"LLM-generated or user-authored prompt templates with typos; mixing Jinja/Handlebars syntax ({{#if}}, {% if %}) with Go templates; edits that dropped an {{end}}.","solutions":["Read the wrapped parse error — it names the template line/position of the syntax problem; fix that action.","Validate the template locally with text/template or http://golang.org/pkg/text/template playground before storing it.","Ensure only Go template syntax is used (no Handlebars/Jinja constructs).","Balance all {{if}}/{{range}}/{{with}} blocks with matching {{end}}."],"exampleFix":"// before\ntmpl := \"Hello {{ .Name\" // missing closing braces\nvars, err := validator.ExtractTemplateVariables(tmpl)\n// after\ntmpl := \"Hello {{ .Name }}\"\nvars, err := validator.ExtractTemplateVariables(tmpl)","handlingStrategy":"validation","validationCode":"if _, err := template.New(\"check\").Funcs(funcMap).Parse(tmpl); err != nil {\n    return fmt.Errorf(\"invalid template: %w\", err)\n}","typeGuard":"func parseableTemplate(s string) bool {\n    _, err := texttemplate.New(\"t\").Parse(s)\n    return err == nil\n}","tryCatchPattern":"vars, err := validator.ExtractTemplateVariables(tmpl)\nvar parseFailed = strings.Contains(err.Error(), \"failed to parse template\")\nif parseFailed {\n    // log err (it names line/offset), return the template to the author for fixing\n}","preventionTips":["Validate templates on save (settings UI, API) using ExtractTemplateVariables before persisting.","Use only Go text/template syntax; reject Handlebars/Jinja constructs at intake.","Balance {{if}}/{{range}}/{{with}} with {{end}} — lint with a template checker.","Round-trip test LLM-generated templates through the parser before use."],"tags":["templates","go-template","parsing","validation"],"backgroundTag":"template-parse-error","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}