Billionmail/BillionMail · error
the recipient has unsubscribed from the current group and…
Error message
the recipient has unsubscribed from the current group and cannot send
What it means
rebuildPostfixServiceNetworks1 (the second, type-checked rebuild variant) requires the parsed docker-compose config to expose a top-level 'services' mapping. It throws this error when dockerConfig lacks the key or it is not map[string]interface{}, indicating the file is not a recognizable docker-compose document.
Solutions
- Check the compose file has a top-level 'services:' mapping with correct indentation
- Re-validate/re-parse the YAML and inspect the resulting map before calling the rebuild
- Point the ConfigManager at the correct docker-compose.yml
- Restore the stock BillionMail docker-compose.yml
Example fix
# before
networks:
billionmail-network: {}
# after
services:
postfix-billionmail:
image: billionmail/postfix
networks:
billionmail-network: {} Defensive patterns
Strategy: validation
Validate before calling
if svc, ok := dockerConfig["services"]; !ok || svc == nil {
return fmt.Errorf("docker-compose.yml missing services section")
} Type guard
func isValidComposeDoc(cfg map[string]interface{}) bool {
_, ok := cfg["services"].(map[string]interface{})
return ok
} Try / catch
if err := m.rebuildPostfixServiceNetworks1(dockerConfig, configs); err != nil {
if strings.Contains(err.Error(), "missing 'services' section") {
// re-read / repair the file and re-parse before retrying
}
return err
} Prevention
- Validate YAML parses to a map with a 'services' key before editing
- Protect the compose file from partial writes (atomic rename)
- Keep backups of docker-compose.yml so a corrupted file can be restored quickly
- Point ConfigManager at the verified main compose file path
When it happens
Trigger: Calling rebuildPostfixServiceNetworks1 with a config from a YAML file missing 'services:', an empty file, or YAML where 'services' decodes to a non-map value (nil, array).
Common situations: Corrupted or truncated docker-compose.yml after a failed edit; passing a partial config; pointing the manager at the wrong YAML file (e.g. an env file).
Related errors
- failed to query group
- failed to check unsubscribe
- failed to convert overview data
- Model not found
- Not suppliers found
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/6397c677365fc8e6.
Report an issue: GitHub.
Appendix: source
Thrown at core/internal/controller/batch_mail/batch_mail_v1_api_mail_send.go:215
"update_time": now,
})
if err != nil {
return contact, err
}
groupId, _ := groupResult.LastInsertId()
group.Id = int(groupId)
} else {
count, err := g.DB().Model("bm_contacts").
Where("email", email).
Where("group_id", group.Id).
Where("active", 0).
Count()
if err != nil {
return contact, fmt.Errorf("failed to check unsubscribe: %w", err)
}
if count > 0 {
return contact, fmt.Errorf("the recipient has unsubscribed from the current group and cannot send")
}
}
contactData := g.Map{
"email": email,
"group_id": group.Id,
"active": 1,
"status": 1,
"create_time": now,
}
contactResult, err := g.DB().Model("bm_contacts").
Data(contactData).
OnConflict("email,group_id").
Save()
if err != nil {
return contact, err
}
View on GitHub (pinned to fc36c76c05)