Billionmail/BillionMail · warning

invalid base URL format: %w

Error message

invalid base URL format: %w

What it means

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.

Source

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

	return SaveSupplierConfig(supplierName, *supplierConfig)
}

// Testing validates the supplier's configuration by checking the base URL and API key.
// It performs the following checks:
// 1. Validates the base URL format.
// 2. Tests the accessibility of the base URL by sending a HEAD request.
// 3. Validates the API key by sending a GET request to the models endpoint.
// If any of these checks fail, it returns an error indicating the issue.
func Testing(supplierName, baseUrl, apiKey string) error {
	if supplierName == "" || baseUrl == "" || apiKey == "" {
		return errors.New("supplier name, base URL, and API key are required")
	}

	// Validate base URL format
	parsedUrl, err := url.ParseRequestURI(baseUrl)
	if err != nil {
		return fmt.Errorf("invalid base URL format: %w", err)
	}
	if parsedUrl.Scheme != "http" && parsedUrl.Scheme != "https" {
		return errors.New("base URL must use http or https protocol")
	}
	// Ensure the base URL ends with a slash
	if err := testBaseURLAccessibility(baseUrl); err != nil {
		return fmt.Errorf("base URL accessibility test failed: %w", err)
	}
	// Validate API key by making a request to the models endpoint
	if err := testAPIKeyValidity(baseUrl, apiKey); err != nil {
		return fmt.Errorf("API key validation failed: %w", err)
	}

	return nil
}

// testBaseURLAccessibility checks if the base URL is accessible by sending a HEAD request.
// It returns an error if the request fails or if the response status is not OK (200).

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Ensure baseUrl includes a scheme, e.g. https://api.openai.com/v1
  2. Trim whitespace/newlines from the URL before passing it in
  3. Test the URL locally with url.ParseRequestURI to see the exact wrapped parse error
  4. Use a full absolute origin URL, not a hostname or path fragment

Example fix

// before
err := askai.Testing(name, "localhost:11434", key) // invalid base URL format
// after
err := askai.Testing(name, "http://localhost:11434/v1", key)
Defensive patterns

Strategy: validation

Validate before calling

func validBaseURL(raw string) bool {
    u, err := url.ParseRequestURI(strings.TrimSpace(raw))
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}
if !validBaseURL(baseUrl) {
    return errors.New("base URL must be an absolute http(s) URL, e.g. https://api.example.com/v1")
}

Try / catch

if err := askai.Testing(name, baseUrl, apiKey); err != nil {
    if strings.HasPrefix(err.Error(), "invalid base URL format:") {
        return fmt.Errorf("check the endpoint URL: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling askai.Testing with a baseUrl like 'localhost:11434' (no scheme), 'openai..com', a URL with spaces, or any string url.ParseRequestURI rejects.

Common situations: 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.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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