micro/go-micro · error
failed to create request: %w
Error message
failed to create request: %w
What it means
Thrown in callAPI when http.NewRequestWithContext fails to build the POST request to /v1/chat/completions. net/http returns an error here only for an invalid method or an unparseable URL, so in practice this signals a malformed opts.BaseURL (empty, missing scheme, or containing invalid characters).
Source
Thrown at ai/openai/openai.go:307
return nil
}
s.closed = true
return s.body.Close()
}
// callAPI makes an HTTP request to the OpenAI API
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, map[string]any, error) {
// Marshal request
reqBody, err := json.Marshal(req)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
}
// Build HTTP request
apiURL := strings.TrimRight(p.opts.BaseURL, "/") + "/v1/chat/completions"
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))
if err != nil {
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
// Make request
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, nil, fmt.Errorf("API request failed: %w", err)
}
defer httpResp.Body.Close()
// Read response
respBody, _ := io.ReadAll(httpResp.Body)
if httpResp.StatusCode != http.StatusOK {
return nil, nil, ai.NewHTTPError(httpResp, respBody)
}View on GitHub (pinned to 24529f1404)
Solutions
- Set a valid absolute BaseURL: WithBaseURL("https://api.openai.com")
- Ensure the URL includes the scheme and no spaces/invalid characters
- Validate/normalize the URL (url.Parse) before provider construction
- Fix config loading so empty env vars don't produce an empty BaseURL
Example fix
// before
WithBaseURL(os.Getenv("OPENAI_BASE_URL")) // empty in prod
// after
base := os.Getenv("OPENAI_BASE_URL")
if base == "" {
base = "https://api.openai.com"
}
_ = WithBaseURL(base) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(strings.TrimRight(baseURL, "/") + "/v1/chat/completions")
if err != nil || u.Host == "" {
return fmt.Errorf("invalid BaseURL: %q", baseURL)
} Prevention
- Validate BaseURL with url.Parse at startup
- Provide a sane default (https://api.openai.com) when config is empty
- Fail fast on config load rather than at first API call
When it happens
Trigger: Non-streaming completion calls with opts.BaseURL empty or malformed — e.g. "api.openai.com" without 'https://', containing spaces, or a misparsed config value; the failing URL is BaseURL + "/v1/chat/completions".
Common situations: Missing default BaseURL when the provider is constructed without WithBaseURL; env-driven config where an empty variable wipes the URL; copy-pasted endpoint missing the scheme; unusual characters from a templated config.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- failed to create stream request: %w
- failed to create request: %w
- failed to create stream request: %w
- failed to create request: %w
- failed to create stream request: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/ed2b12631b82784b.
Report an issue: GitHub.