Billionmail/BillionMail · error

supplier does not exist

Error message

supplier does not exist

What it means

RemoveSupplier deletes a supplier's config directory, but first verifies the directory exists at SUPPLIER_CONFIG_PATH/<supplierName>. If it does not exist, deletion is refused with this error instead of silently succeeding.

Source

Thrown at core/internal/service/askai/supplier.go:626

		ApiKey:          apiKey,
		Home:            "",
		Help:            "",
		Status:          true,
		Sort:            100, // Default sort order, can be changed later
		Icon:            "",  // Default icon, can be set later
	}

	return SaveSupplierConfig(supplierName, supplier)
}

// RemoveSupplier deletes a supplier's configuration directory and all its contents.
// It checks if the supplier exists, and if so, it removes the directory and its files
// If the supplier does not exist, it returns an error indicating that the supplier cannot be found.
// This function is useful for cleaning up unused suppliers from the configuration.
func RemoveSupplier(supplierName string) error {
	supplierPath := SUPPLIER_CONFIG_PATH + "/" + supplierName
	if !public.FileExists(supplierPath) {
		return errors.New("supplier does not exist")
	}
	templatePath := SUPPLIER_TEMPLATE_PATH + "/" + supplierName
	if public.FileExists(templatePath) {
		return errors.New("Cannot delete the system's built-in model supplier.")
	}

	err := os.RemoveAll(supplierPath)
	if err != nil {
		return err
	}

	return nil
}

// SetModelTitle updates the title of a model in the supplier's models.json file.
// It reads the existing models, modifies the title of the specified model, and saves the updated list back to the file.
// If the model is not found, it returns an error indicating that the model does not exist.
func SetModelTitle(supplierName string, modelId string, title string) error {

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Confirm the directory exists via public.FileExists(SUPPLIER_CONFIG_PATH+"/"+supplierName) before removing
  2. Check the supplierName spelling and case against the output of the supplier-list API
  3. Treat this error as idempotent success if the goal is 'supplier gone'; skip or log instead of failing

Example fix

// before
err := RemoveSupplier("OpenAI") // case mismatch -> does not exist

// after
path := SUPPLIER_CONFIG_PATH + "/openai"
if public.FileExists(path) {
    err := RemoveSupplier("openai")
}
Defensive patterns

Strategy: validation

Validate before calling

supplierPath := SUPPLIER_CONFIG_PATH + "/" + supplierName
if !public.FileExists(supplierPath) {
    // nothing to delete — skip or log
    return nil
}
return RemoveSupplier(supplierName)

Try / catch

if err := RemoveSupplier(name); err != nil {
    if strings.Contains(err.Error(), "does not exist") {
        // idempotent success: log and continue
    } else { return err }
}

Prevention

When it happens

Trigger: Calling RemoveSupplier with a supplierName that was never created, was already removed, or is misspelled (including case differences on case-sensitive filesystems).

Common situations: Double-delete in retry logic; removing a supplier after a fresh install where only templates exist; typo'd or wrong-case supplier names.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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