{"record":{"id":"7a094f4d392ea80f","repo":"knadh/listmonk","slug":"invalid-e-mail-address","errorCode":null,"errorMessage":"invalid e-mail address","messagePattern":"invalid e-mail address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/utils.go","lineNumber":13,"sourceCode":"package utils\n\nimport (\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"net/mail\"\n\t\"net/url\"\n\t\"path\"\n\t\"strings\"\n)\n\n// ErrInvalidEmail is returned by SanitizeEmail for malformed input.\nvar ErrInvalidEmail = errors.New(\"invalid e-mail address\")\n\n// ValidateEmail reports whether s is a correctly formed bare e-mail address\n// (no display name component).\nfunc ValidateEmail(s string) bool {\n\t_, err := SanitizeEmail(s)\n\treturn err == nil\n}\n\n// SanitizeEmail trims, lowercases, and validates s as a bare e-mail address\n// (no display name) and returns the canonical form. Returns ErrInvalidEmail\n// for anything `mail.ParseAddress` rejects or for input with a display name.\nfunc SanitizeEmail(s string) (string, error) {\n\ts = strings.ToLower(strings.TrimSpace(s))\n\tem, err := mail.ParseAddress(s)\n\tif err != nil || em.Address != s {\n\t\treturn \"\", ErrInvalidEmail\n\t}\n\treturn em.Address, nil","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/internal/utils/utils.go#L1-L31","documentation":"ErrInvalidEmail is the package-level sentinel returned by utils.SanitizeEmail when the input is not a well-formed bare email address (Go net/mail parsing; display-name components are rejected). ValidateEmail builds on it: an address is valid iff SanitizeEmail returns no error. Callers can compare with errors.Is to distinguish format errors from domain-policy rejections.","triggerScenarios":"Calling utils.SanitizeEmail (directly or via importer.SanitizeEmail / ValidateEmail) with a string failing address parsing: empty input, no '@', illegal characters, spaces, or a 'Name <addr>' display-name form.","commonSituations":"Importing CSVs with dirty data; accepting form input without client-side validation; storing 'John <john@x.com>' strings copied from mail clients; untrimmed newlines/tabs inside the address.","solutions":["Trim whitespace and strip display-name components, keeping only the addr-spec before validation.","Fix the offending value to a proper user@domain.tld form.","Use ValidateEmail as a cheap pre-check before persisting or importing.","In your own code, compare with errors.Is(err, utils.ErrInvalidEmail) to branch on invalid format specifically."],"exampleFix":"// before\nemail := \"John Doe <john@acme.com>\"\n// after\nemail := \"john@acme.com\"","handlingStrategy":"validation","validationCode":"if !utils.ValidateEmail(input) {\n    return fmt.Errorf(\"%q is not a valid bare email address\", input)\n}","typeGuard":"func isBareEmail(s string) bool {\n    if strings.Contains(s, \"<\") || strings.Contains(s, \">\") {\n        return false // display-name form is rejected by SanitizeEmail\n    }\n    return utils.ValidateEmail(s)\n}","tryCatchPattern":"addr, err := utils.SanitizeEmail(input)\nif errors.Is(err, utils.ErrInvalidEmail) {\n    return fmt.Errorf(\"invalid email format: %w\", err)\n}","preventionTips":["Validate email syntax at input time, not only at import.","Trim whitespace and strip display names before storing addresses.","Reuse utils.ValidateEmail rather than ad-hoc regexes.","Compare with errors.Is(err, utils.ErrInvalidEmail) for precise branching."],"tags":["email","validation","go","sentinel-error"],"backgroundTag":"invalid-email-format","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}