Billionmail/BillionMail · error

Failed to insert abnormal recipients: %w

Error message

Failed to insert abnormal recipients: %w

What it means

The final step of BatchUpsertAbnormalRecipients bulk-inserts new recipients via Data(insertList).InsertIgnore(). If the multi-row INSERT fails at SQL level, this wrapped error is returned, leaving earlier updates in the batch already applied (no transaction).

Source

Thrown at core/internal/service/abnormal_recipient/abnormal_recipient.go:137

	// 2. Inserting something that doesn't exist
	var insertList []g.Map
	for _, recipient := range recipients {
		if _, ok := existMap[recipient]; !ok {
			insertList = append(insertList, g.Map{
				"recipient":   recipient,
				"count":       1,
				"add_type":    addType,
				"description": description,
				"create_time": now,
			})
		}
	}
	if len(insertList) > 0 {

		_, err := g.DB().Model("abnormal_recipient").Data(insertList).InsertIgnore()
		if err != nil {

			return fmt.Errorf("Failed to insert abnormal recipients: %w", err)
		}
	}

	return nil
}

// BatchUpsertAbnormalRecipientsWithDetails
func BatchUpsertAbnormalRecipientsWithDetails(ctx context.Context, recipientDetails []RecipientDetail, addType int, baseDescription string) error {
	now := time.Now().Unix()

	if len(recipientDetails) == 0 {
		return nil
	}

	recipients := make([]string, len(recipientDetails))
	detailsMap := make(map[string]RecipientDetail)
	for i, detail := range recipientDetails {
		recipients[i] = detail.Email

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Chunk the insert list (e.g. 500-1000 rows).
  2. Ensure insertList rows contain all required NOT NULL columns.
  3. Run the update+insert phases inside a transaction so the batch is atomic.
  4. Verify abnormal_recipient schema matches the g.Map keys.

Example fix

// before
_, err := g.DB().Model("abnormal_recipient").Data(insertList).InsertIgnore()
// after
tx, _ := g.DB().Begin(ctx)
_, err := tx.Model("abnormal_recipient").Data(insertList).InsertIgnore()
if err != nil { tx.Rollback(); return err }
tx.Commit()
Defensive patterns

Strategy: validation

Validate before calling

// before the insert phase
for _, m := range insertList {
	if m["recipient"] == nil || m["recipient"] == "" { return errors.New("blank recipient row") }
}

Try / catch

_, err := g.DB().Model("abnormal_recipient").Data(insertList).InsertIgnore()
if err != nil { return fmt.Errorf("bulk insert %d recipients: %w", len(insertList), err) }

Prevention

When it happens

Trigger: DB unreachable during insert; a required column missing from the map (schema drift); malformed recipient value violating a constraint InsertIgnore does not cover (e.g. NOT NULL on other columns); statement size limits on huge batches.

Common situations: Importing thousands of recipients in one statement and hitting postgres parameter limits; partial batch state after a mid-loop update failure on a previous run.

Related errors


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