{"record":{"id":"9d0d5694622e2e7a","repo":"Billionmail/BillionMail","slug":"supplier-does-not-exist","errorCode":null,"errorMessage":"supplier does not exist","messagePattern":"supplier does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/askai/supplier.go","lineNumber":626,"sourceCode":"\t\tApiKey:          apiKey,\n\t\tHome:            \"\",\n\t\tHelp:            \"\",\n\t\tStatus:          true,\n\t\tSort:            100, // Default sort order, can be changed later\n\t\tIcon:            \"\",  // Default icon, can be set later\n\t}\n\n\treturn SaveSupplierConfig(supplierName, supplier)\n}\n\n// RemoveSupplier deletes a supplier's configuration directory and all its contents.\n// It checks if the supplier exists, and if so, it removes the directory and its files\n// If the supplier does not exist, it returns an error indicating that the supplier cannot be found.\n// This function is useful for cleaning up unused suppliers from the configuration.\nfunc RemoveSupplier(supplierName string) error {\n\tsupplierPath := SUPPLIER_CONFIG_PATH + \"/\" + supplierName\n\tif !public.FileExists(supplierPath) {\n\t\treturn errors.New(\"supplier does not exist\")\n\t}\n\ttemplatePath := SUPPLIER_TEMPLATE_PATH + \"/\" + supplierName\n\tif public.FileExists(templatePath) {\n\t\treturn errors.New(\"Cannot delete the system's built-in model supplier.\")\n\t}\n\n\terr := os.RemoveAll(supplierPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// SetModelTitle updates the title of a model in the supplier's models.json file.\n// It reads the existing models, modifies the title of the specified model, and saves the updated list back to the file.\n// If the model is not found, it returns an error indicating that the model does not exist.\nfunc SetModelTitle(supplierName string, modelId string, title string) error {","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/supplier.go#L608-L644","documentation":"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.","triggerScenarios":"Calling RemoveSupplier with a supplierName that was never created, was already removed, or is misspelled (including case differences on case-sensitive filesystems).","commonSituations":"Double-delete in retry logic; removing a supplier after a fresh install where only templates exist; typo'd or wrong-case supplier names.","solutions":["Confirm the directory exists via public.FileExists(SUPPLIER_CONFIG_PATH+\"/\"+supplierName) before removing","Check the supplierName spelling and case against the output of the supplier-list API","Treat this error as idempotent success if the goal is 'supplier gone'; skip or log instead of failing"],"exampleFix":"// before\nerr := RemoveSupplier(\"OpenAI\") // case mismatch -> does not exist\n\n// after\npath := SUPPLIER_CONFIG_PATH + \"/openai\"\nif public.FileExists(path) {\n    err := RemoveSupplier(\"openai\")\n}","handlingStrategy":"validation","validationCode":"supplierPath := SUPPLIER_CONFIG_PATH + \"/\" + supplierName\nif !public.FileExists(supplierPath) {\n    // nothing to delete — skip or log\n    return nil\n}\nreturn RemoveSupplier(supplierName)","typeGuard":null,"tryCatchPattern":"if err := RemoveSupplier(name); err != nil {\n    if strings.Contains(err.Error(), \"does not exist\") {\n        // idempotent success: log and continue\n    } else { return err }\n}","preventionTips":["Verify existence before delete; treat as idempotent","Use exact supplier names from the listing API, not user-entered strings","Be careful with case sensitivity on the filesystem"],"tags":["configuration","deletion","ai-supplier"],"backgroundTag":"resource-not-found","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}