knadh/listmonk · error
error compiling subject: %v
Error message
error compiling subject: %v
What it means
This error is returned by Template.Compile in models/templates.go when the template's Subject contains template expressions (hasTplExpr detects {{ ... }}) that fail to parse as a Go text/template. The subject is compiled separately from the body with txttpl.New(BaseTpl).Funcs(txttpl.FuncMap(f)).Parse so it can be rendered per-message; a parse failure is wrapped as "error compiling subject: %v". Only tx templates with templated subjects reach this path.
Source
Thrown at models/templates.go:53
Attachments []Attachment `json:"-"`
}
// Compile compiles a template body and subject (only for tx templates) and
// caches the templat references to be executed later.
func (t *Template) Compile(f template.FuncMap) error {
tpl, err := template.New(BaseTpl).Funcs(f).Parse(t.Body)
if err != nil {
return fmt.Errorf("error compiling transactional template: %v", err)
}
t.Tpl = tpl
// If the subject line has a template string, compile it.
if hasTplExpr(t.Subject) {
subj := t.Subject
subjTpl, err := txttpl.New(BaseTpl).Funcs(txttpl.FuncMap(f)).Parse(subj)
if err != nil {
return fmt.Errorf("error compiling subject: %v", err)
}
t.SubjectTpl = subjTpl
}
return nil
}
type CampaignStats struct {
ID int `db:"id" json:"id"`
Status string `db:"status" json:"status"`
ToSend int `db:"to_send" json:"to_send"`
Sent int `db:"sent" json:"sent"`
Started null.Time `db:"started_at" json:"started_at"`
UpdatedAt null.Time `db:"updated_at" json:"updated_at"`
Rate int `json:"rate"`
NetRate int `json:"net_rate"`
}
View on GitHub (pinned to 670c01717d)
Solutions
- Fix the subject template syntax named in the wrapped parse error (balance braces, close all actions, correct end tags).
- Ensure every function used in the subject exists in the FuncMap passed to Compile.
- If the subject needs no per-message templating, remove {{ }} expressions so it is stored and used literally.
- Validate the subject with text/template.Parse in a quick standalone test before saving the template.
- Audit existing subject lines after upgrading the library in case available template functions changed.
Example fix
// before
t.Subject = "Receipt for {{ .Subscriber.Name "
// after
t.Subject = "Receipt for {{ .Subscriber.Name }}" Defensive patterns
Strategy: validation
Validate before calling
import ("strings" "text/template")
func validateTemplateSubject(subject string, funcs template.FuncMap) error {
if subject == "" || !strings.Contains(subject, "{{") {
return nil
}
_, err := template.New("subject").Funcs(funcs).Parse(subject)
return err
} Type guard
func subjectIsTemplated(subject string) bool {
return strings.Contains(subject, "{{") && strings.Contains(subject, "}}")
} Try / catch
if err := tpl.Compile(funcs); err != nil {
if strings.HasPrefix(err.Error(), "error compiling subject") {
return fmt.Errorf("template subject is not valid Go text/template syntax: %w", err)
}
return err
} Prevention
- Parse-check templated subjects with text/template before saving the template.
- Keep subject templates simple: plain field references like {{ .Subscriber.Name }}.
- Ensure all subject functions exist in the FuncMap passed to Compile.
- Add form/UI-level validation that rejects unbalanced braces in subject inputs.
- Re-validate stored templates after upgrading the library in case FuncMap functions changed.
When it happens
Trigger: Calling CreateTemplate/UpdateTemplate (or previewTemplate/CacheTpl) on a Template whose Subject is non-empty, contains {{ ... }}, and is syntactically invalid — unclosed action, unknown function name, malformed pipeline, or unbalanced braces.
Common situations: Typo in a custom template function inside the subject line, pasting HTML-template pipelines valid only in html/template, stray braces from hand editing the subject in the admin UI, removing/renaming a FuncMap function that existing subject lines still reference.
Related errors
- error compiling alt body: %v
- error compiling subject: %v
- error compiling transactional template: %v
- 'email' column not found
- token was not found or has expired
AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01).
Data as JSON: /api/errors/7bf799cd0ffd89fc.
Report an issue: GitHub.