Billionmail/BillionMail · error

HostWorkDir not set

Error message

HostWorkDir not set

What it means

InitQuotaPluginAndUpdateUsedSpace configures the Dovecot quota plugin and needs the host working directory to locate on-disk config and maildir paths. If public.HostWorkDir is empty (never initialized at startup), it refuses to proceed with this sentinel error.

Source

Thrown at core/internal/service/mail_boxes/init_quota_plugin.go:27

	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gfile"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"
)

// Initialize quota plugin. If not installed, install it first.
// Modify dovecot.conf, 20-pop3.conf, and 90-quota.conf.
// Rebuild dovecot-sql.conf.ext
// Check all mailboxes and add the maildirsize file (make sure the file permissions are correct)

func InitQuotaPluginAndUpdateUsedSpace(ctx context.Context) error {
	if public.HostWorkDir == "" {
		return errors.New("HostWorkDir not set")
	}

	markPath := public.AbsPath("../core/data/quota_init_done.mark")

	if gfile.Exists(markPath) {
		return nil
	}

	confRoot := public.AbsPath("../conf/dovecot")

	if _, err := os.Stat(confRoot); os.IsNotExist(err) {
		return fmt.Errorf("dovecot conf dir not found: %s", confRoot)
	}

	// 1. Modify dovecot.conf
	if err := ensureDovecotConf(confRoot); err != nil {
		return err
	}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Ensure the application bootstrap sets public.HostWorkDir before calling this function
  2. Verify the work-dir config/env var is present in the deployment and parsed at startup
  3. In scripts/tests, set public.HostWorkDir manually to the repo/deployment root before invoking
  4. Run the init via the normal application startup path rather than a bare entrypoint

Example fix

// before
err := mail_boxes.InitQuotaPluginAndUpdateUsedSpace(ctx)
// after
if public.HostWorkDir == "" {
	public.HostWorkDir = os.Getenv("BM_WORK_DIR") // or standard bootstrap
}
if err := mail_boxes.InitQuotaPluginAndUpdateUsedSpace(ctx); err != nil {
	g.Log().Error(ctx, "quota init failed", err)
}
Defensive patterns

Strategy: validation

Validate before calling

if public.HostWorkDir == "" {
	public.HostWorkDir = os.Getenv("BM_WORK_DIR")
}
if public.HostWorkDir == "" {
	return errors.New("HostWorkDir not set; configure work dir before quota init")
}

Try / catch

if err := mail_boxes.InitQuotaPluginAndUpdateUsedSpace(ctx); err != nil && err.Error() == "HostWorkDir not set" {
	log.Printf("bootstrap incomplete: set HostWorkDir before quota init")
}

Prevention

When it happens

Trigger: Calling InitQuotaPluginAndUpdateUsedSpace before application bootstrap populated public.HostWorkDir, or the init code that sets HostWorkDir was skipped/misordered (e.g. running the function from a standalone script or test).

Common situations: Deployment where the work-dir env/config is missing so bootstrap leaves HostWorkDir empty; calling the init routine from a cron job with a minimal entrypoint that skips normal app init; unit tests invoking the function without fixtures.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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