knadh/listmonk · error
campaigns.fieldInvalidBody
Error message
campaigns.fieldInvalidBody
What it means
validateCampaignFields compiles the campaign body as a Go template via c.CompileTemplate(a.manager.TemplateFuncs(&camp)); any template parse/compile failure becomes campaigns.fieldInvalidBody with the underlying error interpolated. It guards against invalid template syntax or references to undefined template functions.
Source
Thrown at cmd/campaigns.go:733
}
}
if len(c.ListIDs) == 0 {
return c, errors.New(a.i18n.T("campaigns.fieldInvalidListIDs"))
}
if !a.manager.HasMessenger(c.Messenger) {
// If it's a specific SMTP, but it's no longer available (removed/disabled), fall back to general email messenger.
if strings.HasPrefix(c.Messenger, "email-") {
c.Messenger = "email"
} else {
return c, errors.New(a.i18n.Ts("campaigns.fieldInvalidMessenger", "name", c.Messenger))
}
}
camp := models.Campaign{Body: c.Body, TemplateBody: tplTag}
if err := c.CompileTemplate(a.manager.TemplateFuncs(&camp)); err != nil {
return c, errors.New(a.i18n.Ts("campaigns.fieldInvalidBody", "error", err.Error()))
}
if len(c.Headers) == 0 {
c.Headers = make([]map[string]string, 0)
}
// Validate and initialize attribs.
if c.Attribs != nil {
if _, err := json.Marshal(c.Attribs); err != nil {
return c, errors.New(a.i18n.T("subscribers.invalidJSON"))
}
}
if len(c.ArchiveMeta) == 0 {
c.ArchiveMeta = json.RawMessage("{}")
}
if c.ArchiveSlug.String != "" {View on GitHub (pinned to 670c01717d)
Solutions
- Fix the template syntax reported in the interpolated error message — typically an unclosed {{ }} or bad expression.
- Escape literal braces not meant as templates (e.g. use {{ "{{" }} or avoid them) in CSS/JS or Angular-style code.
- Replace unknown function calls with ones registered in TemplateFuncs (e.g. use built-in newsletter functions).
- Compile the body locally with text/template and the same func map to reproduce the exact parse error before submitting.
Example fix
// before
{"body": "<div ng-if="{{user.active}}">Hi</div>"}
// after
{"body": "<div data-active="{{ if .Subscriber.Status }}1{{ end }}">Hi</div>"} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-compile the body with Go's text/template rules before calling the API
// (in Go)
_, err := template.New("body").Funcs(myFuncs).Parse(campaignBody)
if err != nil {
return fmt.Errorf("campaign body template error: %w", err)
} Try / catch
try {
await api.createCampaign({ body, ...rest });
} catch (e) {
if (e.message.includes('fieldInvalidBody')) {
// e.message embeds the underlying Go template error
throw new Error(`Fix campaign body template: ${e.message}`);
}
throw e;
} Prevention
- Test template bodies on a test campaign before production sends.
- Escape literal '{{' in CSS/JS content that should not be templated.
- Only call template functions registered by the app; check docs for the list.
- Keep templates from other engines (Handlebars, Vue) out of campaign bodies.
When it happens
Trigger: Campaign body containing malformed Go template syntax (unclosed {{ }}, bad pipelines) or calling template functions that don't exist in the manager's TemplateFuncs, on create/update/test campaign calls.
Common situations: Pasting HTML with stray '{{' characters (e.g. CSS/JS or Angular/Vue bindings) that Go templates try to parse; typos in custom template function names; template tags from another system (Handlebars {{#if}}) used verbatim.
Related errors
- campaigns.fieldInvalidSubject
- campaigns.fieldInvalidFromEmail
- campaigns.fieldInvalidName
- campaigns.fieldInvalidSendAt
- campaigns.fieldInvalidListIDs
AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01).
Data as JSON: /api/errors/cf380246b1e7b9d5.
Report an issue: GitHub.