Billionmail/BillionMail · error

the recipient has unsubscribed from the current group and ca

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.

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)

Solutions

  1. Check the compose file has a top-level 'services:' mapping with correct indentation
  2. Re-validate/re-parse the YAML and inspect the resulting map before calling the rebuild
  3. Point the ConfigManager at the correct docker-compose.yml
  4. 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

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


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