{"record":{"id":"c571afc8501a97ef","repo":"Billionmail/BillionMail","slug":"alert-settings-file-not-found","errorCode":null,"errorMessage":"alert settings file not found","messagePattern":"alert settings file not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/internal/service/domains/blacklist.go","lineNumber":457,"sourceCode":"\t}\n\n\tg.Log().Infof(ctx, \"✅ Blacklist alert sent successfully for domain: %s to %d recipients\", domain, len(alertSettings.RecipientList))\n}\n\ntype BlacklistAlertSettings struct {\n\tName          string   `json:\"name\"`\n\tSenderEmail   string   `json:\"sender_email\"`\n\tSMTPPassword  string   `json:\"smtp_password\"`\n\tSMTPServer    string   `json:\"smtp_server\"`\n\tSMTPPort      int      `json:\"smtp_port\"`\n\tRecipientList []string `json:\"recipient_list\"`\n}\n\nfunc loadBlacklistAlertSettingsForAlert() (*BlacklistAlertSettings, error) {\n\talertSettingsFile := public.AbsPath(\"../core/data/blacklist_alert_settings.json\")\n\n\tif !gfile.Exists(alertSettingsFile) {\n\t\treturn nil, fmt.Errorf(\"alert settings file not found\")\n\t}\n\n\tcontent := gfile.GetContents(alertSettingsFile)\n\tif content == \"\" {\n\t\treturn nil, fmt.Errorf(\"alert settings file is empty\")\n\t}\n\n\tvar settings BlacklistAlertSettings\n\terr := json.Unmarshal([]byte(content), &settings)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse alert settings: %v\", err)\n\t}\n\n\treturn &settings, nil\n}\n\nfunc sendAlertEmail(ctx context.Context, settings *BlacklistAlertSettings, subject, body string) error {\n","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/domains/blacklist.go#L439-L475","documentation":"loadBlacklistAlertSettingsForAlert reads blacklist alert configuration from ../core/data/blacklist_alert_settings.json (resolved via public.AbsPath) and returns this error when gfile.Exists reports the file is missing. It is a guard so sendBlacklistAlert can skip alerting (rather than crash) when the admin has never configured blacklist alerts.","triggerScenarios":"sendBlacklistAlert fires (an IP/domain was found blacklisted) but ../core/data/blacklist_alert_settings.json does not exist — i.e. no one saved alert settings yet, or the file was deleted/moved.","commonSituations":"Fresh BillionMail install where alert settings were never configured; data directory recreated or volume not mounted so the JSON is lost; container deployment where ../core/data path resolution differs from the host volume; file deleted by cleanup scripts.","solutions":["Create/configure blacklist alert settings in the UI so the JSON file is written to core/data/blacklist_alert_settings.json","Verify the data volume is mounted and persists at the expected AbsPath location","Confirm the process working directory makes public.AbsPath(\"../core/data/...\") resolve to the real data dir","Treat this as an expected condition: skip alerting and log an informational message rather than an error"],"exampleFix":"// before\nif !gfile.Exists(alertSettingsFile) {\n\treturn nil, fmt.Errorf(\"alert settings file not found\")\n}\n// after\nif !gfile.Exists(alertSettingsFile) {\n\tg.Log().Infof(ctx, \"blacklist alert settings not configured at %s; skipping alert\", alertSettingsFile)\n\treturn nil, nil\n}","handlingStrategy":"validation","validationCode":"settingsPath := public.AbsPath(\"../core/data/blacklist_alert_settings.json\")\nif !gfile.Exists(settingsPath) {\n\t// alerts not configured: skip silently or prompt admin to configure\n\treturn nil\n}","typeGuard":"func alertSettingsConfigured() bool {\n\treturn gfile.Exists(public.AbsPath(\"../core/data/blacklist_alert_settings.json\"))\n}","tryCatchPattern":"settings, err := loadBlacklistAlertSettingsForAlert()\nif err != nil {\n\tif err.Error() == \"alert settings file not found\" {\n\t\tg.Log().Info(ctx, \"blacklist alerts not configured; skipping\")\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Configure blacklist alert settings during initial setup so the file exists","Mount core/data as a persistent volume across container rebuilds","Verify the process working directory keeps AbsPath(\"../core/data\") pointing at the real data dir","Alert admins once at startup if the settings file is absent"],"tags":["configuration","filesystem","blacklist"],"backgroundTag":"missing-config-file","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}