Billionmail/BillionMail · error

failed to load email templates: %v

Error message

failed to load email templates: %v

What it means

preloadData loads email_templates rows for the template IDs collected from the API templates. A failure of the SELECT on email_templates is wrapped as "failed to load email templates: %v". It indicates a database-level error during the read, not that a template row is absent.

Source

Thrown at core/internal/service/batch_mail/api_mail_send.go:386

		WhereIn("id", apiIds).
		Ctx(ctx).
		Scan(&apiTemplates)
	if err != nil {
		return nil, fmt.Errorf("failed to load API templates: %v", err)
	}
	// Collect template IDs
	templateIds := make([]int, 0, len(apiTemplates))
	for _, t := range apiTemplates {
		templateIds = append(templateIds, t.TemplateId)
	}
	// Batch query email templates
	var emailTemplates []entity.EmailTemplate
	err = g.DB().Model("email_templates").
		WhereIn("id", templateIds).
		Ctx(ctx).
		Scan(&emailTemplates)
	if err != nil {
		return nil, fmt.Errorf("failed to load email templates: %v", err)
	}
	// Batch query contacts
	var contacts []entity.Contact
	err = g.DB().Model("bm_contacts").
		WhereIn("email", recipientEmails).
		Ctx(ctx).
		Scan(&contacts)
	if err != nil {
		return nil, fmt.Errorf("failed to load contacts: %v", err)
	}
	// Build cache
	cache := &CacheData{
		ApiTemplates:   make(map[int]entity.ApiTemplates),
		EmailTemplates: make(map[int]entity.EmailTemplate),
		Contacts:       make(map[string]entity.Contact),
	}

	for _, t := range apiTemplates {

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Inspect the wrapped underlying error in logs to identify the DB failure cause
  2. Confirm email_templates table schema and run pending migrations
  3. Check DB connectivity/credentials and retry queue processing
  4. Ensure connection pool limits are adequate for concurrent batch workers
Defensive patterns

Strategy: retry

Validate before calling

if len(templateIds) == 0 {
    return nil, errors.New("no template ids collected from API templates")
}

Try / catch

cache, err := preloadData(ctx, apiIds)
if err != nil {
    if strings.Contains(err.Error(), "failed to load email templates") {
        // log underlying cause, requeue for retry
    }
    return err
}

Prevention

When it happens

Trigger: ProcessApiMailQueue -> preloadData when the SELECT ... WHERE id IN (templateIds) on email_templates fails: DB unreachable, permissions, schema mismatch, or the earlier api_templates query succeeded but the connection dropped between queries.

Common situations: Connection reset mid-batch under heavy load; migration renamed columns on email_templates; DB user denied SELECT on that table; Postgres failover during processing.

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/5ad5ca50a65cd9cc. Report an issue: GitHub.