{"record":{"id":"e10154cdcdaf22f5","repo":"usememos/memos","slug":"from-email-is-required","errorCode":null,"errorMessage":"from email is required","messagePattern":"from email is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/email/config.go","lineNumber":39,"sourceCode":"\tFromEmail string\n\t// FromName is the display name that will appear in the \"From\" field\n\tFromName string\n\t// UseTLS enables STARTTLS encryption (recommended for port 587)\n\tUseTLS bool\n\t// UseSSL enables SSL/TLS encryption (for port 465)\n\tUseSSL bool\n}\n\n// Validate checks if the configuration is valid.\nfunc (c *Config) Validate() error {\n\tif c.SMTPHost == \"\" {\n\t\treturn errors.New(\"SMTP host is required\")\n\t}\n\tif c.SMTPPort <= 0 || c.SMTPPort > 65535 {\n\t\treturn errors.New(\"SMTP port must be between 1 and 65535\")\n\t}\n\tif c.FromEmail == \"\" {\n\t\treturn errors.New(\"from email is required\")\n\t}\n\treturn nil\n}\n\n// GetServerAddress returns the SMTP server address in the format \"host:port\".\nfunc (c *Config) GetServerAddress() string {\n\treturn fmt.Sprintf(\"%s:%d\", c.SMTPHost, c.SMTPPort)\n}\n","sourceCodeStart":21,"sourceCodeEnd":48,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/email/config.go#L21-L48","documentation":"Returned by Config.Validate() when FromEmail is empty. The sender address is mandatory for the SMTP MAIL FROM command and the message headers, so a Config without it is rejected before connecting. Like the host and port checks, this is a fail-fast guard on incomplete mailer configuration.","triggerScenarios":"Config constructed with FromEmail unset — the admin SMTP form's 'from' field left blank, or a config map missing the from key so the struct field stays \"\".","commonSituations":"Filling host/port but skipping the sender field in settings; renaming the config key (from vs fromEmail vs sender) so the loader never populates it; deploying with a templated config where the from variable expands to empty.","solutions":["Set FromEmail to a real mailbox you control at the sending domain (e.g., noreply@example.com).","Check the config key that populates FromEmail matches what the loader expects.","If the from address comes from a template/env var, assert it is non-empty at deploy time."],"exampleFix":"// before\ncfg := email.Config{SMTPHost: \"smtp.example.com\", SMTPPort: 587}\n\n// after\ncfg := email.Config{SMTPHost: \"smtp.example.com\", SMTPPort: 587, FromEmail: \"noreply@example.com\"}","handlingStrategy":"validation","validationCode":"// Go\nif !strings.Contains(cfg.FromEmail, \"@\") {\n  return errors.New(\"from email missing or invalid\")\n}\nif err := cfg.Validate(); err != nil {\n  return err\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Validate(); err != nil {\n  return errors.Wrap(err, \"invalid SMTP config\")\n}","preventionTips":["Make 'from address' a required field in the admin UI with basic format validation.","Add a 'send test email' button that calls Validate() first so misconfig is caught at save time.","Assert templated from-addresses expand non-empty in CI/deploy checks."],"tags":["smtp","email","configuration","validation","go"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}