{"record":{"id":"80984ad29bb877d8","repo":"knadh/listmonk","slug":"campaigns-fieldinvalidlistids","errorCode":null,"errorMessage":"campaigns.fieldInvalidListIDs","messagePattern":"campaigns\\.fieldInvalidListIDs","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/campaigns.go","lineNumber":719,"sourceCode":"\t\tc.ContentType != models.CampaignContentTypePlain &&\n\t\tc.ContentType != models.CampaignContentTypeVisual &&\n\t\tc.ContentType != models.CampaignContentTypeMarkdown {\n\t\tc.ContentType = models.CampaignContentTypeRichtext\n\t}\n\n\tif c.ContentType != models.CampaignContentTypeVisual {\n\t\tc.BodySource.Valid = false\n\t}\n\n\t// If there's a \"send_at\" date, it should be in the future.\n\tif c.SendAt.Valid {\n\t\tif c.SendAt.Time.Before(time.Now()) {\n\t\t\treturn c, errors.New(a.i18n.T(\"campaigns.fieldInvalidSendAt\"))\n\t\t}\n\t}\n\n\tif len(c.ListIDs) == 0 {\n\t\treturn c, errors.New(a.i18n.T(\"campaigns.fieldInvalidListIDs\"))\n\t}\n\n\tif !a.manager.HasMessenger(c.Messenger) {\n\t\t// If it's a specific SMTP, but it's no longer available (removed/disabled), fall back to general email messenger.\n\t\tif strings.HasPrefix(c.Messenger, \"email-\") {\n\t\t\tc.Messenger = \"email\"\n\t\t} else {\n\t\t\treturn c, errors.New(a.i18n.Ts(\"campaigns.fieldInvalidMessenger\", \"name\", c.Messenger))\n\t\t}\n\t}\n\n\tcamp := models.Campaign{Body: c.Body, TemplateBody: tplTag}\n\tif err := c.CompileTemplate(a.manager.TemplateFuncs(&camp)); err != nil {\n\t\treturn c, errors.New(a.i18n.Ts(\"campaigns.fieldInvalidBody\", \"error\", err.Error()))\n\t}\n\n\tif len(c.Headers) == 0 {\n\t\tc.Headers = make([]map[string]string, 0)","sourceCodeStart":701,"sourceCodeEnd":737,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/cmd/campaigns.go#L701-L737","documentation":"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.","triggerScenarios":"CreateCampaign, UpdateCampaign, or TestCampaign with 'lists' (ListIDs) missing, empty array, or null in the request body.","commonSituations":"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.","solutions":["Include at least one valid list ID in the lists array of the request.","Create a list first (POST /api/lists) if none exists, then reference its ID.","In the UI, disable submit until a list is selected; validate client-side.","Verify list IDs are integers and that the array is non-null."],"exampleFix":"// before\n{\"name\": \"News\", \"lists\": []}\n// after\n{\"name\": \"News\", \"lists\": [1, 3]}","handlingStrategy":"validation","validationCode":"function requireLists(listIds) {\n  if (!Array.isArray(listIds) || listIds.length === 0) {\n    throw new Error('at least one list id is required');\n  }\n  if (!listIds.every(n => Number.isInteger(n) && n > 0)) {\n    throw new Error('all list ids must be positive integers');\n  }\n}","typeGuard":"function hasListIds(v: unknown): v is number[] {\n  return Array.isArray(v) && v.length > 0 && v.every((n): n is number => Number.isInteger(n));\n}","tryCatchPattern":"try {\n  await api.createCampaign({ lists: listIds, ...rest });\n} catch (e) {\n  if (e.message.includes('fieldInvalidListIDs')) {\n    throw new Error('Select at least one subscriber list before creating the campaign');\n  }\n  throw e;\n}","preventionTips":["Enforce list selection in the UI before enabling submit.","Ensure list IDs are integers, not stringified IDs.","Validate that referenced lists still exist (they may have been deleted)."],"tags":["validation","campaign","lists"],"backgroundTag":"missing-required-argument","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}