Billionmail/BillionMail · error
API key validation failed: %w
Error message
API key validation failed: %w
What it means
Testing validates the API key by issuing a GET to the /models endpoint via testAPIKeyValidity. Any failure there (non-200/401/404 status, network error, bad request) is wrapped as 'API key validation failed: %w'. The wrapped cause reveals whether it was auth-related or another HTTP problem.
Source
Thrown at core/internal/service/askai/supplier.go:501
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).
func testBaseURLAccessibility(baseUrl string) error {
client := &http.Client{Timeout: 3 * time.Second}
resp, err := client.Head(baseUrl)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
// testAPIKeyValidity checks if the provided API key is valid by making a GET request to the models endpoint.View on GitHub (pinned to fc36c76c05)
Solutions
- Inspect the wrapped inner error/status to see the actual response code
- Re-copy the API key from the provider dashboard and confirm it matches the chosen baseUrl's provider
- Check the account/key status on the provider side (revoked, expired, no credit)
- Test the key manually: curl -H 'Authorization: Bearer <key>' <baseUrl>/models
- Verify the endpoint path exists for the provider version in use
Example fix
// before
err := askai.Testing(name, url, "sk-...truncated") // key malformed
// after
apiKey := strings.TrimSpace(os.Getenv("PROVIDER_API_KEY"))
if apiKey == "" || len(apiKey) < 20 { return errors.New("API key looks invalid") }
err := askai.Testing(name, url, apiKey) Defensive patterns
Strategy: try-catch
Validate before calling
func keyLooksPlausible(key string) bool {
k := strings.TrimSpace(key)
return len(k) >= 20 && !strings.ContainsAny(k, " \n\t")
}
if !keyLooksPlausible(apiKey) { return errors.New("API key missing or malformed") } Try / catch
if err := askai.Testing(name, baseUrl, apiKey); err != nil {
var detail string
if strings.HasPrefix(err.Error(), "API key validation failed:") {
detail = strings.TrimPrefix(err.Error(), "API key validation failed: ")
return fmt.Errorf("check your key at the provider dashboard: %s", detail)
}
return err
} Prevention
- Re-copy keys directly from the provider dashboard; avoid manual retyping
- Trim whitespace/newlines around stored keys
- Ensure the key's provider matches the baseUrl's provider
- Check account status (active, funded, not revoked) before testing
When it happens
Trigger: Calling askai.Testing with an invalid, revoked, or malformed API key; the models endpoint returning an unexpected status (403, 500); network failure during the GET request.
Common situations: Copied key missing characters or containing whitespace; key revoked or rotated on the provider side; key valid for a different provider/endpoint than baseUrl points to; provider outage returning 5xx; account lacks access to the models endpoint (403).
Related errors
- invalid API key
- base URL accessibility test failed: %w
- unexpected API response: %d %s
- request context is nil
- supplier configuration not found
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/790a2b0f9970d291.
Report an issue: GitHub.