{"record":{"id":"388e5e9da7fb8713","repo":"knadh/listmonk","slug":"error-compiling-alt-body-v","errorCode":null,"errorMessage":"error compiling alt body: %v","messagePattern":"error compiling alt body: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"models/messages.go","lineNumber":96,"sourceCode":"\tdata := struct {\n\t\tSubscriber Subscriber\n\t\tTx         *TxMessage\n\t}{sub, m}\n\n\t// Render the body.\n\tb := bytes.Buffer{}\n\tif err := tpl.Tpl.ExecuteTemplate(&b, BaseTpl, data); err != nil {\n\t\treturn err\n\t}\n\tm.Body = make([]byte, b.Len())\n\tcopy(m.Body, b.Bytes())\n\tb.Reset()\n\n\t// Render alt body if it has any templating strings.\n\tif m.AltBody != \"\" && hasTplExpr(m.AltBody) {\n\t\tt, err := txttpl.New(BaseTpl).Funcs(funcs).Parse(m.AltBody)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error compiling alt body: %v\", err)\n\t\t}\n\t\tif err := t.ExecuteTemplate(&b, BaseTpl, data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm.AltBody = b.String()\n\t\tb.Reset()\n\t}\n\n\t// Was a subject provided in the message?\n\tvar (\n\t\tsubjTpl *txttpl.Template\n\t\tsubject = m.Subject\n\t)\n\tif subject != \"\" {\n\t\tif hasTplExpr(m.Subject) {\n\t\t\t// If the subject has a template string, render that.\n\t\t\ts, err := txttpl.New(BaseTpl).Funcs(funcs).Parse(m.Subject)\n\t\t\tif err != nil {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/models/messages.go#L78-L114","documentation":"This error comes from TxMessage.Render in models/messages.go when the message's plain-text AltBody contains template expressions ({{ ... }}) that fail to PARSE against Go's text/template engine. Render compiles AltBody as its own txttemplate before executing it; a parse failure (bad syntax, unknown function, unclosed action) is wrapped as \"error compiling alt body: %v\". It is a compile-time template syntax problem, not a rendering/execution failure.","triggerScenarios":"Calling SendTxMessage (or previewTemplate) with a TxMessage whose AltBody contains {{ ... }} template strings that are syntactically invalid — e.g. {{ .Tx.AltBody }}} with an extra brace, {{ .Subscriber.Name | titlexx }} referencing a func missing from the provided FuncMap, or an unclosed {{ if }} block.","commonSituations":"Hand-written alt bodies with stray braces (e.g. CSS/JS snippets inside the text part), typos in template function names registered in the FuncMap, copying HTML template syntax (html/template pipelines) into the text part, or an upgrade changing the available template functions.","solutions":["Fix the template syntax in TxMessage.AltBody reported in the wrapped error (unbalanced {{ }}, bad pipeline, missing end tag).","Verify every function used in AltBody exists in the FuncMap passed to Render (from the campaign/messenger template funcs).","If the alt body has no templating needs, remove {{ }} expressions entirely — Render only compiles AltBody when hasTplExpr() detects template strings.","Test the alt body with text/template.Parse in a scratch Go program to reproduce and isolate the parse error.","Check for html/template-specific constructs ({{ define }} with context escaping, URL filters) that text/template may not accept as written."],"exampleFix":"// before\nm.AltBody = \"Hi {{ .Subscriber.Name }}, your total is {{ .Tx.Amount }\"\n// after\nm.AltBody = \"Hi {{ .Subscriber.Name }}, your total is {{ .Tx.Amount }}\"","handlingStrategy":"validation","validationCode":"import (\"strings\" \"text/template\")\n\nfunc validateAltBody(altBody string, funcs template.FuncMap) error {\n\tif !strings.Contains(altBody, \"{{\") {\n\t\treturn nil // no template expression, Render won't compile it\n\t}\n\t_, err := template.New(\"alt\").Funcs(funcs).Parse(altBody)\n\treturn err\n}","typeGuard":"func isTemplated(s string) bool {\n\treturn strings.Contains(s, \"{{\") && strings.Contains(s, \"}}\")\n}","tryCatchPattern":"if err := msg.Render(sub, tpl, funcs); err != nil {\n\tif strings.HasPrefix(err.Error(), \"error compiling alt body\") {\n\t\tlog.Errorf(\"alt body template syntax invalid: %v\", err)\n\t\t// fall back to the raw AltBody or a static default, or reject the send\n\t\treturn fmt.Errorf(\"rejecting tx message: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Test every AltBody through text/template.Parse before submitting via SendTxMessage.","Keep CSS/JS braces out of alt bodies, or escape {{ and }} using template literals.","Only call template functions that are registered in the FuncMap the messenger passes to Render.","Keep alt bodies minimal — reuse the HTML body rendering rather than duplicating templating logic.","Add a pre-send lint step in CI that parses all stored transactional message fields."],"tags":["go","text-template","template-syntax","compilation"],"backgroundTag":"template-syntax-error","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}