Billionmail/BillionMail · error

invalid recipient email format: %s

Error message

invalid recipient email format: %s

What it means

Each entry in RecipientList is sanity-checked with strings.Contains(recipient, "@"). A recipient without an @ sign is not a valid email address and causes validation to abort, echoing the offending value in the message.

Source

Thrown at core/internal/controller/settings/settings_v1_set_blacklist_alert_settings.go:93

	if settings.SMTPServer == "" {
		return fmt.Errorf("SMTP server is required")
	}

	if settings.SMTPPort < 1 || settings.SMTPPort > 65535 {
		return fmt.Errorf("SMTP port must be between 1 and 65535")
	}

	if settings.SMTPPassword == "" {
		return fmt.Errorf("SMTP password is required")
	}

	if len(settings.RecipientList) == 0 {
		return fmt.Errorf("at least one recipient is required")
	}

	for _, recipient := range settings.RecipientList {
		if !strings.Contains(recipient, "@") {
			return fmt.Errorf("invalid recipient email format: %s", recipient)
		}
	}

	return nil
}

func testSMTPConnectionWithRelay(ctx context.Context, settings *v1.SetBlacklistAlertSettingsReq) error {
	//g.Log().Infof(ctx, "Testing SMTP connection to %s:%d", settings.SMTPServer, settings.SMTPPort)

	result := relay.TestSmtpConnection(
		settings.SMTPServer,
		fmt.Sprintf("%d", settings.SMTPPort),
		settings.SenderEmail,
		settings.SMTPPassword,
	)

	if !result.Success {
		return fmt.Errorf("%s", result.Message)

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Split comma/semicolon-separated input into individual addresses before sending, trimming whitespace.
  2. Remove or correct the entry named in the error message so it is a full address like user@domain.com.
  3. Optionally strengthen the server check to a regex/net/mail.ParseAddress to catch more malformed formats.

Example fix

// before
recipientList: ["admin@example.com,ops@example.com"]
// after
recipientList: ["admin@example.com", "ops@example.com"]
Defensive patterns

Strategy: validation

Validate before calling

const emailRe = /^[^@\s]+@[^@\s]+\.[^@\s]+$/
for (const r of payload.recipientList) {
  if (!emailRe.test(r.trim())) throw new Error(`Invalid recipient email: ${r}`)
}

Type guard

function isEmail(v: unknown): v is string {
  return typeof v === 'string' && v.includes('@') && v.trim() === v && v.length > 3
}

Try / catch

try {
  await api.setBlacklistAlertSettings(payload)
} catch (e) {
  const m = String(e).match(/invalid recipient email format: (.+)/)
  if (m) showFormError('recipients', `Fix this address: ${m[1]}`)
}

Prevention

When it happens

Trigger: Calling SetBlacklistAlertSettings where any string in recipientList lacks the '@' character (e.g. 'adminexample.com', a bare name, or a comma-joined string 'a@x.com,b@x.com').

Common situations: User pastes a comma-separated list into a single input instead of adding one per field; whitespace or name-only entries; CSV upload where the email column was misparsed.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/e3055cf4d5ddf13c. Report an issue: GitHub.