Billionmail/BillionMail · error
getSenderIdentitiesForIp err: %v
Error message
getSenderIdentitiesForIp err: %v
What it means
getSenderIdentitiesForIp in the warmup service queries the 'domain' table (active = 1) for all sender-identity domain names. If the GoFrame DB query fails — connection refused, bad credentials, missing table/column, or context cancellation — the error is wrapped as 'getSenderIdentitiesForIp err' and propagated to EvaluateScoreForProvider and EvaluateIpScore. It indicates the warmup scoring pipeline could not load domains from the database.
Source
Thrown at core/internal/service/warmup/sender_ip_warmup.go:41
minSendVolumeForFullScoring = 20 // The minimum sending volume required for a full score calculation
)
type SenderIpWarmupService struct{}
var insSenderIpWarmupService = SenderIpWarmupService{}
func SenderIpWarmup() *SenderIpWarmupService {
return &insSenderIpWarmupService
}
// getSenderIdentitiesForIp gets the associated sender identities (e.g., email addresses or domains) for a given sender IP.
func (s *SenderIpWarmupService) getSenderIdentitiesForIp(ctx context.Context, senderIp string) (domains []string, err error) {
// Get the sender identities associated with this IP.
var vals []gdb.Value
vals, err = g.DB().Ctx(ctx).Model("domain").Where("active = 1").Fields("domain").Array("domain")
if err != nil {
err = fmt.Errorf("getSenderIdentitiesForIp err: %v", err)
return
}
for _, v := range vals {
domains = append(domains, v.String())
}
g.Log().Debug(ctx, "Domains for IP", senderIp, domains)
return // return empty, let the scoring logic handle the absence of data
}
// InitializeOrGetWarmupStatus initializes or retrieves the warmup status of an IP.
func (s *SenderIpWarmupService) InitializeOrGetWarmupStatus(ctx context.Context, senderIp string) (record *entity.SenderIpWarmup, err error) {
err = g.DB().Model("bm_sender_ip_warmup").Ctx(ctx).Where("sender_ip", senderIp).Scan(&record)
if err != nil {
g.Log().Errorf(ctx, "Failed to query SenderIpWarmup for IP %s: %v", senderIp, err)
returnView on GitHub (pinned to fc36c76c05)
Solutions
- Check the wrapped error for the concrete DB cause (connection vs SQL syntax vs missing column).
- Verify DB connectivity and credentials (g.DB() config, psql test).
- Run pending migrations; confirm the domain table has active and domain columns.
- Check DB logs at query time for lock/pool exhaustion.
- Add reconnect/pool health checks if failures are intermittent.
Example fix
// before
vals, err = g.DB().Ctx(ctx).Model("domain").Where("active = 1").Fields("domain").Array("domain")
if err != nil {
err = fmt.Errorf("getSenderIdentitiesForIp err: %v", err)
return
}
// after
vals, err = g.DB().Ctx(ctx).Model("domain").Where("active = 1").Fields("domain").Array("domain")
if err != nil {
err = fmt.Errorf("getSenderIdentitiesForIp err: %w", err)
return
} Defensive patterns
Strategy: retry
Validate before calling
// health-check the DB before running warmup scoring
if err := g.DB().Ctx(ctx).Exec("SELECT 1"); err != nil {
return fmt.Errorf("database unavailable: %w", err)
}
// verify schema exists
n, err := g.DB().Ctx(ctx).Model("domain").Count()
if err != nil {
return fmt.Errorf("domain table missing/unreadable: %w", err)
}
_ = n Try / catch
domains, err := svc.getSenderIdentitiesForIp(ctx, ip)
if err != nil {
if ctx.Err() != nil {
return fmt.Errorf("warmup scoring cancelled: %w", ctx.Err())
}
// transient DB error: retry with backoff
return fmt.Errorf("warmup scoring skipped: %w", err)
} Prevention
- Run migrations as part of deployment and verify the domain schema
- Add DB health checks/readiness probes before starting warmup workers
- Set sane connection-pool limits and monitor pool saturation
- Use %w instead of %v when wrapping so errors.As/Is work
When it happens
Trigger: PostgreSQL/DB down or unreachable, wrong DB credentials in config, 'domain' table or 'active'/'domain' columns missing or renamed after a migration, query context cancelled by shutdown or deadline.
Common situations: Fresh deployment where migrations didn't run, misconfigured database DSN, DB connection pool exhausted, schema drift between code and migrations during upgrades.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- failed to get recipient count: %w
- failed to get contacts trend: %w
- failed to query relay domain mappings: %v
- failed to get all domains: %w
- fail to check domain: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/f74585f7ad064763.
Report an issue: GitHub.