{"record":{"id":"5ad324f70505aadf","repo":"Billionmail/BillionMail","slug":"invalid-base-url-format-w","errorCode":null,"errorMessage":"invalid base URL format: %w","messagePattern":"invalid base URL format: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/internal/service/askai/supplier.go","lineNumber":490,"sourceCode":"\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}\n\n\treturn nil\n}\n\n// testBaseURLAccessibility checks if the base URL is accessible by sending a HEAD request.\n// It returns an error if the request fails or if the response status is not OK (200).","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/supplier.go#L472-L508","documentation":"Testing validates the base URL with url.ParseRequestURI. If the string is not a parseable absolute URI, the parse error is wrapped as 'invalid base URL format: %w'. This catches malformed URLs before any network request is attempted.","triggerScenarios":"Calling askai.Testing with a baseUrl like 'localhost:11434' (no scheme), 'openai..com', a URL with spaces, or any string url.ParseRequestURI rejects.","commonSituations":"User omits 'https://' when typing the endpoint; trailing spaces or newline characters pasted into a config field; IPv6 or unusual hosts not handled by ParseRequestURI; copying a path instead of a full URL.","solutions":["Ensure baseUrl includes a scheme, e.g. https://api.openai.com/v1","Trim whitespace/newlines from the URL before passing it in","Test the URL locally with url.ParseRequestURI to see the exact wrapped parse error","Use a full absolute origin URL, not a hostname or path fragment"],"exampleFix":"// before\nerr := askai.Testing(name, \"localhost:11434\", key) // invalid base URL format\n// after\nerr := askai.Testing(name, \"http://localhost:11434/v1\", key)","handlingStrategy":"validation","validationCode":"func validBaseURL(raw string) bool {\n    u, err := url.ParseRequestURI(strings.TrimSpace(raw))\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}\nif !validBaseURL(baseUrl) {\n    return errors.New(\"base URL must be an absolute http(s) URL, e.g. https://api.example.com/v1\")\n}","typeGuard":null,"tryCatchPattern":"if err := askai.Testing(name, baseUrl, apiKey); err != nil {\n    if strings.HasPrefix(err.Error(), \"invalid base URL format:\") {\n        return fmt.Errorf(\"check the endpoint URL: %w\", err)\n    }\n    return err\n}","preventionTips":["Always include the scheme (https://) in endpoint URLs","Trim whitespace and newlines from pasted URLs","Pre-fill known provider URLs from a dropdown instead of free text","Validate with url.ParseRequestURI before calling Testing"],"tags":["go","validation","url","supplier"],"backgroundTag":"invalid-url-format","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"}