charmbracelet/crush · error
failed to create request for provider %s: %w
Error message
failed to create request for provider %s: %w
What it means
Wraps an error from http.NewRequestWithContext while building the probe request used to validate a provider's API key. Since the method and body are constants, this almost always means the target URL is invalid (unparseable). The provider ID is included to identify which configured endpoint caused it.
Source
Thrown at internal/config/config.go:1020
if strings.HasPrefix(apiKey, "ABSK") { // Bedrock API keys
return nil
}
return errors.New("not a valid bedrock api key")
case catwalk.TypeVercel:
// NOTE: Vercel does not validate API keys on the `/models` endpoint.
if strings.HasPrefix(apiKey, "vck_") { // Vercel API keys
return nil
}
return errors.New("not a valid vercel api key")
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
client := &http.Client{}
req, err := http.NewRequestWithContext(ctx, "GET", testURL, nil)
if err != nil {
return fmt.Errorf("failed to create request for provider %s: %w", c.ID, err)
}
for k, v := range headers {
req.Header.Set(k, v)
}
for k, v := range c.ExtraHeaders {
req.Header.Set(k, v)
}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to create request for provider %s: %w", c.ID, err)
}
defer resp.Body.Close()
switch providerID {
case catwalk.InferenceProviderZAI:
if resp.StatusCode == http.StatusUnauthorized {
return fmt.Errorf("failed to connect to provider %s: %s", c.ID, resp.Status)View on GitHub (pinned to 7944b8e522)
Solutions
- Check the provider's base_url in crushrc/crush.json for typos and ensure it is a valid absolute http(s) URL.
- If the URL comes from an env variable, print it (echo $VAR) and fix the value.
- Re-copy the endpoint URL from the provider's documentation.
- Run the URL through a quick parse check (e.g. `python3 -c "import urllib.parse;urllib.parse.urlparse('...')"`) to confirm validity.
Example fix
// before (crushrc) provider myprovider base_url "https://api.example.com/ v1" // space makes URL unparseable end // after provider myprovider base_url "https://api.example.com/v1" end
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(baseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("provider base_url %q is not a valid absolute URL", baseURL)
} Type guard
func isValidURL(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
if err := validateProviderKey(ctx, cfg); err != nil {
if strings.Contains(err.Error(), "failed to create request") {
log.Fatalf("fix base_url for %s: %v", cfg.ID, err)
}
return err
} Prevention
- Validate custom base URLs at config-load time with url.Parse.
- Never hand-edit URLs with editors that insert soft hyphens/spaces.
- Source endpoint URLs from provider docs or env, not ad-hoc edits.
When it happens
Trigger: API-key validation against a provider whose resolved test URL (base URL or path in the provider catalog) cannot be parsed by net/url — e.g. a custom base_url in crushrc containing spaces, control characters, or missing scheme artifacts.
Common situations: A hand-edited custom base URL with a typo ("htp://", spaces, trailing braces); an env-resolved base URL that expanded to an empty or malformed string; copy-pasting a URL with invisible characters.
Related errors
- failed to create request: %w
- mcp http config requires a non-empty 'url' field
- could not create request: %w
- not a valid bedrock api key
- not a valid vercel api key
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/30bc27b6e4a18b87.
Report an issue: GitHub.