{"record":{"id":"d6590b844ca9cb0c","repo":"knadh/listmonk","slug":"campaigns-fieldinvalidfromemail","errorCode":null,"errorMessage":"campaigns.fieldInvalidFromEmail","messagePattern":"campaigns\\.fieldInvalidFromEmail","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/campaigns.go","lineNumber":685,"sourceCode":"\t}\n\n\t// Create a sample campaign message.\n\tmsg, err := a.manager.NewCampaignMessage(camp, sub)\n\tif err != nil {\n\t\ta.log.Printf(\"error rendering message: %v\", err)\n\t\treturn echo.NewHTTPError(http.StatusNotFound, a.i18n.Ts(\"templates.errorRendering\", \"error\", err.Error()))\n\t}\n\n\treturn a.manager.PushCampaignMessage(msg)\n}\n\n// validateCampaignFields validates incoming campaign field values.\nfunc (a *App) validateCampaignFields(c campReq) (campReq, error) {\n\tif c.FromEmail == \"\" {\n\t\tc.FromEmail = a.cfg.FromEmail\n\t} else if !reFromAddress.Match([]byte(c.FromEmail)) {\n\t\tif _, err := a.importer.SanitizeEmail(c.FromEmail); err != nil {\n\t\t\treturn c, errors.New(a.i18n.T(\"campaigns.fieldInvalidFromEmail\"))\n\t\t}\n\t}\n\n\tif !strHasLen(c.Name, 1, stdInputMaxLen) {\n\t\treturn c, errors.New(a.i18n.T(\"campaigns.fieldInvalidName\"))\n\t}\n\n\t// Larger char limit for subject as it can contain {{ go templating }} logic.\n\tif !strHasLen(c.Subject, 1, 5000) {\n\t\treturn c, errors.New(a.i18n.T(\"campaigns.fieldInvalidSubject\"))\n\t}\n\n\t// If no content-type is specified, default to richtext.\n\tif c.ContentType != models.CampaignContentTypeRichtext &&\n\t\tc.ContentType != models.CampaignContentTypeHTML &&\n\t\tc.ContentType != models.CampaignContentTypePlain &&\n\t\tc.ContentType != models.CampaignContentTypeVisual &&\n\t\tc.ContentType != models.CampaignContentTypeMarkdown {","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/cmd/campaigns.go#L667-L703","documentation":"validateCampaignFields in cmd/campaigns.go rejects a campaign request whose FromEmail is neither empty nor empty-defaulted from config, when it fails both the reFromAddress regex and importer.SanitizeEmail(). It means the supplied sender address is not a parseable/valid e-mail the outgoing mail system can use.","triggerScenarios":"POST/PUT campaign endpoints (CreateCampaign, UpdateCampaign) or TestCampaign with a from_email value like 'not-an-email', 'John <john>' (malformed), or containing stray whitespace/characters that fail both the regex and sanitization.","commonSituations":"Typing a display name into the from_email field instead of an address, pasting 'Name <addr@x.com>' when the API expects just the address, or copying an address with hidden unicode/whitespace from a document.","solutions":["Send a plain valid e-mail address (e.g. 'sender@domain.com') in the from_email field.","Omit from_email entirely to inherit the default a.cfg.FromEmail configured in the app config.","Strip whitespace/display-name wrappers before sending; use net/mail.ParseAddress client-side to pre-validate.","If a display name is needed, configure the sender name field separately rather than embedding '<>' in the address."],"exampleFix":"// before\n{\"from_email\": \"Marketing <marketing@example.com>\"}\n// after\n{\"from_email\": \"marketing@example.com\", \"from_name\": \"Marketing\"}","handlingStrategy":"validation","validationCode":"// validate from_email before calling the campaign API\nfunction isValidFromEmail(v) {\n  return /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(String(v || '').trim());\n}\n// or, omit the field to inherit the server default:\nconst payload = { name, subject, lists };\nif (fromEmail) payload.from_email = fromEmail;","typeGuard":"function isPlainEmail(v: unknown): v is string {\n  return typeof v === 'string' && /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(v.trim());\n}","tryCatchPattern":"try {\n  await api.createCampaign(payload);\n} catch (e) {\n  if (e.message.includes('fieldInvalidFromEmail')) {\n    throw new Error(`from_email \"${payload.from_email}\" is not a valid address`);\n  }\n  throw e;\n}","preventionTips":["Never embed display names like 'Name <addr>' in from_email; use the separate name field.","Trim whitespace and strip zero-width characters before sending.","Prefer omitting from_email to use the app-wide default sender."],"tags":["email","validation","campaign"],"backgroundTag":"invalid-email-address","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}