knadh/listmonk · error

campaigns.fieldInvalidListIDs

Error message

campaigns.fieldInvalidListIDs

What it means

validateCampaignFields requires at least one target list: if len(c.ListIDs) == 0 it returns campaigns.fieldInvalidListIDs. A campaign is only meaningful when addressed to subscriber lists, so the empty case is rejected.

Solutions

  1. Include at least one valid list ID in the lists array of the request.
  2. Create a list first (POST /api/lists) if none exists, then reference its ID.
  3. In the UI, disable submit until a list is selected; validate client-side.
  4. Verify list IDs are integers and that the array is non-null.

Example fix

// before
{"name": "News", "lists": []}
// after
{"name": "News", "lists": [1, 3]}
Defensive patterns

Strategy: validation

Validate before calling

function requireLists(listIds) {
  if (!Array.isArray(listIds) || listIds.length === 0) {
    throw new Error('at least one list id is required');
  }
  if (!listIds.every(n => Number.isInteger(n) && n > 0)) {
    throw new Error('all list ids must be positive integers');
  }
}

Type guard

function hasListIds(v: unknown): v is number[] {
  return Array.isArray(v) && v.length > 0 && v.every((n): n is number => Number.isInteger(n));
}

Try / catch

try {
  await api.createCampaign({ lists: listIds, ...rest });
} catch (e) {
  if (e.message.includes('fieldInvalidListIDs')) {
    throw new Error('Select at least one subscriber list before creating the campaign');
  }
  throw e;
}

Prevention

When it happens

Trigger: CreateCampaign, UpdateCampaign, or TestCampaign with 'lists' (ListIDs) missing, empty array, or null in the request body.

Common situations: Front-end allowing campaign creation before the user selects recipients; automation scripts copying payloads that had lists stripped; sending list IDs as strings instead of integers and ending up with an empty parsed array.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at cmd/campaigns.go:719

		c.ContentType != models.CampaignContentTypePlain &&
		c.ContentType != models.CampaignContentTypeVisual &&
		c.ContentType != models.CampaignContentTypeMarkdown {
		c.ContentType = models.CampaignContentTypeRichtext
	}

	if c.ContentType != models.CampaignContentTypeVisual {
		c.BodySource.Valid = false
	}

	// If there's a "send_at" date, it should be in the future.
	if c.SendAt.Valid {
		if c.SendAt.Time.Before(time.Now()) {
			return c, errors.New(a.i18n.T("campaigns.fieldInvalidSendAt"))
		}
	}

	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)

View on GitHub (pinned to 670c01717d)