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.

Solutions

  1. Fix the template syntax reported in the interpolated error message — typically an unclosed {{ }} or bad expression.
  2. Escape literal braces not meant as templates (e.g. use {{ "{{" }} or avoid them) in CSS/JS or Angular-style code.
  3. Replace unknown function calls with ones registered in TemplateFuncs (e.g. use built-in newsletter functions).
  4. 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

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


AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01). Data as JSON: /api/errors/cf380246b1e7b9d5. Report an issue: GitHub.

Appendix: 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)