Billionmail/BillionMail · error

error saving images configuration: %v

Error message

error saving images configuration: %v

What it means

UploadImage returns this when the follow-up SaveImagesConfig call fails to write the updated images.json after a successful CDN upload. The uploaded image exists remotely but its metadata record was not persisted, wrapping the write error.

Source

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

	if err != nil {
		return "", err
	}

	if resultData.Status == false {
		return "", fmt.Errorf("upload image failed: %s", resultData.Msg)
	}

	imageInfo.ImageUrl = resultData.Data.URL

	// Save the image information to the images.json file
	images, err := ReadImagesConfig(Domain)
	if err != nil {
		return "", fmt.Errorf("error reading images configuration: %v", err)
	}
	images = append(images, imageInfo)
	err = SaveImagesConfig(Domain, images)
	if err != nil {
		return "", fmt.Errorf("error saving images configuration: %v", err)
	}

	return imageInfo.ImageUrl, nil
}

// ModifyImage updates the alt text and image tag of an existing image in the images configuration.
// It reads the existing images configuration, modifies the specified fields for the image with the given ID and saves the updated configuration back to the file.
// If the images configuration file does not exist or cannot be read, it returns an error.
func ModifyImage(Domain string, ImageId string, AltText string, ImageTag string) error {
	images, err := ReadImagesConfig(Domain)
	if err != nil {
		return fmt.Errorf("error reading images configuration: %v", err)
	}
	for i, image := range images {
		if image.ImageId == ImageId {
			// Update the AltText and ImageTag if they are not empty
			if AltText != "" {
				images[i].AltText = AltText

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Create the directory before writing (os.MkdirAll in SaveImagesConfig) and fix permissions.
  2. Check disk space and mount flags on the config volume.
  3. Verify PRODUCT_CONFIG_PATH is correct for the runtime environment.
  4. Retry the save; note the CDN image is already uploaded so only metadata persistence needs repairing.

Example fix

// before
err = SaveImagesConfig(Domain, images)
if err != nil {
	return "", fmt.Errorf("error saving images configuration: %v", err)
}
// after
if err := SaveImagesConfig(Domain, images); err != nil {
	return "", fmt.Errorf("error saving images configuration (domain=%s): %v", Domain, err)
}
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Join(PRODUCT_CONFIG_PATH, Domain)
if err := os.MkdirAll(dir, 0755); err != nil {
	return err
}
if f, err := os.OpenFile(filepath.Join(dir, "images.json"), os.O_WRONLY|os.O_CREATE, 0644); err != nil {
	return fmt.Errorf("not writable: %v", err)
} else {
	f.Close()
}

Try / catch

url, err := UploadImage(domain, imagePath, info)
if err != nil && strings.Contains(err.Error(), "error saving images configuration") {
	// CDN image exists; retry metadata save or queue for reconciliation
}

Prevention

When it happens

Trigger: UploadImage reaches SaveImagesConfig with the appended record and os.WriteFile fails: target directory missing, permission denied, disk full, or read-only filesystem.

Common situations: First image saved for a domain whose config directory was never created; container volume went read-only; disk quota exceeded.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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