Billionmail/BillionMail · error

error reading images configuration file: %v

Error message

error reading images configuration file: %v

What it means

ReadImagesConfig returns this when os.ReadFile fails on PRODUCT_CONFIG_PATH/<Domain>/images.json. Note the code pre-creates the file with '[]' if missing, so a read failure usually means the file exists but is unreadable (permissions, path mismatch), or the WriteFile seeding call failed silently and the file is still absent.

Source

Thrown at core/internal/service/askai/project.go:912

	data, err := json.MarshalIndent(images, "", "  ")
	if err != nil {
		return fmt.Errorf("error marshalling images: %v", err)
	}
	err = os.WriteFile(imagesPath, data, 0644)
	if err != nil {
		return fmt.Errorf("error saving images file: %v", err)
	}
	return nil
}

func ReadImagesConfig(Domain string) ([]ImageInfo, error) {
	imagesPath := fmt.Sprintf("%s/%s/images.json", PRODUCT_CONFIG_PATH, Domain)
	if !public.FileExists(imagesPath) {
		os.WriteFile(imagesPath, []byte("[]"), 0644)
	}
	data, err := os.ReadFile(imagesPath)
	if err != nil {
		return []ImageInfo{}, fmt.Errorf("error reading images configuration file: %v", err)
	}

	var images []ImageInfo
	err = json.Unmarshal(data, &images)
	if err != nil {
		return []ImageInfo{}, fmt.Errorf("error unmarshalling images configuration: %v", err)
	}
	return images, nil
}

type UploadImageResponse struct {
	Status bool   `json:"status"`
	Msg    string `json:"msg"`
	Data   struct {
		URL string `json:"url"`
	} `json:"data"`
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check that PRODUCT_CONFIG_PATH/<Domain>/images.json exists and is readable by the service user (ls -l).
  2. Fix the seeding code to create the directory and check its error: os.MkdirAll + handle the WriteFile error instead of ignoring it.
  3. Verify PRODUCT_CONFIG_PATH is the intended path in the running environment.
  4. If race-prone, tolerate os.IsNotExist by returning an empty slice instead of an error.

Example fix

// before
if !public.FileExists(imagesPath) {
	os.WriteFile(imagesPath, []byte("[]"), 0644)
}
data, err := os.ReadFile(imagesPath)
if err != nil {
	return []ImageInfo{}, fmt.Errorf("error reading images configuration file: %v", err)
}
// after
dir := filepath.Dir(imagesPath)
if err := os.MkdirAll(dir, 0755); err != nil {
	return []ImageInfo{}, fmt.Errorf("error creating images dir: %v", err)
}
if !public.FileExists(imagesPath) {
	if err := os.WriteFile(imagesPath, []byte("[]"), 0644); err != nil {
		return []ImageInfo{}, fmt.Errorf("error seeding images file: %v", err)
	}
}
data, err := os.ReadFile(imagesPath)
if os.IsNotExist(err) {
	return []ImageInfo{}, nil
}
if err != nil {
	return []ImageInfo{}, fmt.Errorf("error reading images configuration file: %v", err)
}
Defensive patterns

Strategy: fallback

Validate before calling

p := filepath.Join(PRODUCT_CONFIG_PATH, Domain, "images.json")
if fi, err := os.Stat(p); err != nil {
	return fmt.Errorf("images.json missing: %s", p)
} else if fi.IsDir() {
	return fmt.Errorf("images.json path is a directory")
}
if f, err := os.Open(p); err != nil {
	return fmt.Errorf("images.json unreadable: %v", err)
} else {
	f.Close()
}

Try / catch

images, err := ReadImagesConfig(domain)
if err != nil && strings.Contains(err.Error(), "reading images configuration file") {
	images = []ImageInfo{} // treat unreadable file as empty
}

Prevention

When it happens

Trigger: Calling ReadImagesConfig (directly or via UploadImage/ModifyImage/RemoveImage) when the seeded os.WriteFile([]byte("[]")) in the existence check fails (directory missing, permission denied) and then os.ReadFile errors.

Common situations: PRODUCT_CONFIG_PATH misconfigured after redeploy; config dir mounted read-only or with wrong ownership; the seeding write failing because the directory doesn't exist.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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