{"record":{"id":"92d09234666901e7","repo":"Billionmail/BillionMail","slug":"supplier-name-base-url-and-api-key-are-required","errorCode":null,"errorMessage":"supplier name, base URL, and API key are required","messagePattern":"supplier name, base URL, and API key are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/internal/service/askai/supplier.go","lineNumber":484,"sourceCode":"\tif err != nil {\n\t\treturn errors.New(\"supplier configuration not found\")\n\t}\n\n\tsupplierConfig.BaseUrl = baseUrl\n\tsupplierConfig.ApiKey = apiKey\n\n\treturn SaveSupplierConfig(supplierName, *supplierConfig)\n}\n\n// Testing validates the supplier's configuration by checking the base URL and API key.\n// It performs the following checks:\n// 1. Validates the base URL format.\n// 2. Tests the accessibility of the base URL by sending a HEAD request.\n// 3. Validates the API key by sending a GET request to the models endpoint.\n// If any of these checks fail, it returns an error indicating the issue.\nfunc Testing(supplierName, baseUrl, apiKey string) error {\n\tif supplierName == \"\" || baseUrl == \"\" || apiKey == \"\" {\n\t\treturn errors.New(\"supplier name, base URL, and API key are required\")\n\t}\n\n\t// Validate base URL format\n\tparsedUrl, err := url.ParseRequestURI(baseUrl)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid base URL format: %w\", err)\n\t}\n\tif parsedUrl.Scheme != \"http\" && parsedUrl.Scheme != \"https\" {\n\t\treturn errors.New(\"base URL must use http or https protocol\")\n\t}\n\t// Ensure the base URL ends with a slash\n\tif err := testBaseURLAccessibility(baseUrl); err != nil {\n\t\treturn fmt.Errorf(\"base URL accessibility test failed: %w\", err)\n\t}\n\t// Validate API key by making a request to the models endpoint\n\tif err := testAPIKeyValidity(baseUrl, apiKey); err != nil {\n\t\treturn fmt.Errorf(\"API key validation failed: %w\", err)\n\t}","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/supplier.go#L466-L502","documentation":"Testing performs a connectivity/credential check of an AI supplier (URL reachability plus API key validation). Before doing any network work it requires all three inputs — supplierName, baseUrl, apiKey — to be non-empty; otherwise it returns this validation error immediately.","triggerScenarios":"Calling askai.Testing with any of: empty supplier name, empty base URL, or empty API key.","commonSituations":"Form fields not yet filled in by the user when a 'test connection' button is clicked; API key not loaded from environment/storage (empty env var); supplier name lost during state passing.","solutions":["Ensure supplierName, baseUrl, and apiKey are all non-empty before calling Testing","Load the API key from the proper source (config, env, secret store) and confirm it is populated","Add client-side required-field validation on the form that feeds Testing"],"exampleFix":"// before\nerr := askai.Testing(name, baseUrl, apiKey) // apiKey was \"\"\n// after\nif name == \"\" || baseUrl == \"\" || apiKey == \"\" {\n    return fmt.Errorf(\"fill in supplier name, base URL, and API key before testing\")\n}\nerr := askai.Testing(name, baseUrl, apiKey)","handlingStrategy":"validation","validationCode":"func inputsReady(name, baseUrl, apiKey string) bool {\n    return strings.TrimSpace(name) != \"\" && strings.TrimSpace(baseUrl) != \"\" && strings.TrimSpace(apiKey) != \"\"\n}\nif !inputsReady(supplierName, baseUrl, apiKey) {\n    return errors.New(\"all fields are required before testing\")\n}","typeGuard":null,"tryCatchPattern":"if err := askai.Testing(name, baseUrl, apiKey); err != nil {\n    if err.Error() == \"supplier name, base URL, and API key are required\" {\n        return fmt.Errorf(\"please fill in all supplier fields\")\n    }\n    return err\n}","preventionTips":["Add required-field validation in the UI before invoking Testing","Trim inputs; empty-after-trim is as bad as empty","Load API keys from env/secret store and fail fast if unset","Never call Testing with zero-value struct fields — check them first"],"tags":["go","validation","supplier","input"],"backgroundTag":"missing-required-argument","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"}