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)
		return

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check the wrapped error for the concrete DB cause (connection vs SQL syntax vs missing column).
  2. Verify DB connectivity and credentials (g.DB() config, psql test).
  3. Run pending migrations; confirm the domain table has active and domain columns.
  4. Check DB logs at query time for lock/pool exhaustion.
  5. 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

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


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