{"record":{"id":"5c52b5ee99656881","repo":"Billionmail/BillionMail","slug":"supplier-configuration-is-incomplete-cannot-set-s","errorCode":null,"errorMessage":"supplier configuration is incomplete, cannot set status","messagePattern":"supplier configuration is incomplete, cannot set status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/askai/supplier.go","lineNumber":567,"sourceCode":"\t}\n}\n\n// GetSupplierConfig retrieves the configuration for a specific supplier by its name.\n// It reads the configuration file and returns a Supplier struct containing the supplier's details.\n// If the configuration file does not exist or an error occurs, it returns an error.\nfunc GetSupplierConfig(supplierName string) (*Supplier, error) {\n\treturn ReadSupplierConfig(supplierName)\n}\n\n// SetSupplierStatus updates the status of a supplier in its configuration file.\n// It reads the existing configuration, modifies the status, and saves it back to the file.\nfunc SetSupplierStatus(supplierName string, status bool) error {\n\tsupplierConfig, err := ReadSupplierConfig(supplierName)\n\tif err != nil {\n\t\treturn errors.New(\"supplier configuration not found\")\n\t}\n\tif supplierConfig.ApiKey == \"\" || supplierConfig.BaseUrl == \"\" {\n\t\treturn errors.New(\"supplier configuration is incomplete, cannot set status\")\n\t}\n\tsupplierConfig.Status = status\n\n\treturn SaveSupplierConfig(supplierName, *supplierConfig)\n}\n\n// SetModelStatus updates the status of a specific model in the supplier's models.json file.\n// It reads the existing models, modifies the status 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 SetModelStatus(supplierName string, modelId string, status bool) error {\n\tmodelsFile := SUPPLIER_CONFIG_PATH + \"/\" + supplierName + \"/models.json\"\n\n\t// Read existing models\n\texistingModels := GetModelList(supplierName)\n\n\t// Update the model status\n\tfor i, model := range existingModels {\n\t\tif model.ModelId == modelId {","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/supplier.go#L549-L585","documentation":"SetSupplierStatus reads a supplier's config and refuses to toggle status when essential fields are blank. If ApiKey or BaseUrl is empty, the supplier is considered non-functional, so enabling/disabling it is rejected. This prevents activating a half-configured supplier that would fail at request time.","triggerScenarios":"Calling SetSupplierStatus(name, true/false) for a supplier whose config file exists but has an empty ApiKey or BaseUrl, e.g. after AddSupplier was interrupted or the config JSON was hand-edited.","commonSituations":"Manually created or partially saved supplier config files; a supplier created without an API key (free-tier/no-key supplier); config file corrupted or fields removed during migration.","solutions":["Read the supplier config and populate ApiKey and BaseUrl (re-run AddSupplier or edit the config JSON), then call SetSupplierStatus again","Verify SUPPLIER_CONFIG_PATH/<name> contains valid JSON with non-empty api_key and base_url fields","If the supplier is unwanted, remove it with RemoveSupplier and recreate it with complete credentials"],"exampleFix":"// before: toggling a supplier with empty key\nSetSupplierStatus(\"openai\", true) // -> \"supplier configuration is incomplete\"\n\n// after: repair config first\ncfg, _ := ReadSupplierConfig(\"openai\")\ncfg.ApiKey = os.Getenv(\"OPENAI_API_KEY\")\ncfg.BaseUrl = \"https://api.openai.com/v1\"\nSaveSupplierConfig(\"openai\", *cfg)\nSetSupplierStatus(\"openai\", true)","handlingStrategy":"validation","validationCode":"func canSetStatus(supplierName string) error {\n    cfg, err := ReadSupplierConfig(supplierName)\n    if err != nil { return err }\n    if cfg.ApiKey == \"\" || cfg.BaseUrl == \"\" {\n        return errors.New(\"complete api_key and base_url before toggling status\")\n    }\n    return nil\n}\n// call canSetStatus(name) before SetSupplierStatus","typeGuard":"func supplierConfigComplete(cfg *Supplier) bool {\n    return cfg != nil && cfg.ApiKey != \"\" && cfg.BaseUrl != \"\"\n}","tryCatchPattern":"if err := SetSupplierStatus(name, true); err != nil {\n    if strings.Contains(err.Error(), \"configuration is incomplete\") {\n        // repair config then retry\n    } else { return err }\n}","preventionTips":["Always create suppliers via AddSupplier with both baseUrl and apiKey populated","Validate config JSON after manual edits or migrations","Alert on suppliers whose ApiKey/BaseUrl are empty during startup checks"],"tags":["configuration","validation","ai-supplier"],"backgroundTag":"incomplete-supplier-config","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}