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.EmailView on GitHub (pinned to fc36c76c05)
Solutions
- Chunk the insert list (e.g. 500-1000 rows).
- Ensure insertList rows contain all required NOT NULL columns.
- Run the update+insert phases inside a transaction so the batch is atomic.
- 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
- Chunk inserts to ~500 rows
- Fill all NOT NULL columns in each g.Map
- Wrap update+insert in one transaction for atomicity
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
- Failed to add exception recipient: %w
- Failed to remove exception recipient: %w
- Failed to get exception recipient: %w
- Failed to query existing abnormal recipients: %w
- Failed to update abnormal recipient: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/e47a02a0dee7e5bf.
Report an issue: GitHub.