micro/go-micro · error

API request failed: %w

Error message

API request failed: %w

What it means

This error wraps the underlying transport error returned by http.DefaultClient.Do when sending a chat-completion request to the OpenAI API. The library uses it to signal that no HTTP response was received at all (DNS failure, connection refused, TLS problem, context cancellation, etc.). The original *url.Error is preserved via %w so callers can errors.As/Is into it.

Source

Thrown at ai/openai/openai.go:317

	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)
	}

	// Parse response
	var chatResp struct {
		Usage struct {
			PromptTokens     int `json:"prompt_tokens"`
			CompletionTokens int `json:"completion_tokens"`
			TotalTokens      int `json:"total_tokens"`
		} `json:"usage"`
		Choices []struct {
			Message struct {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Verify opts.BaseURL is a valid absolute URL with scheme, e.g. https://api.openai.com
  2. Check network connectivity / proxy env vars (HTTPS_PROXY) from the machine running the code
  3. Unwrap with errors.As to *url.Error and inspect err.Err/err.Unwrap for the root cause
  4. Check that the ctx passed to the call has a sane deadline; increase it for long generations

Example fix

// before
provider := openai.NewProvider(openai.WithBaseURL("api.openai.com"))
// after
provider := openai.NewProvider(openai.WithBaseURL("https://api.openai.com"))
Defensive patterns

Strategy: try-catch

Validate before calling

u, err := url.Parse(cfg.BaseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid BaseURL %q: %w", cfg.BaseURL, err)
}
if _, err := net.LookupHost(u.Hostname()); err != nil {
    return fmt.Errorf("host %q unreachable: %w", u.Hostname(), err)
}

Type guard

var urlErr *url.Error
if errors.As(err, &urlErr) {
    // urlErr.Op, urlErr.URL, urlErr.Err describe the transport failure
}

Try / catch

resp, err := provider.Generate(ctx, req)
if err != nil {
    var urlErr *url.Error
    if errors.As(err, &urlErr) {
        return fmt.Errorf("openai transport failure for %s: %w", urlErr.URL, urlErr.Err)
    }
    return err
}

Prevention

When it happens

Trigger: callAPI posts to <BaseURL>/v1/chat/completions and http.DefaultClient.Do returns a non-nil error: unreachable host, bad BaseURL, proxy failure, TLS handshake failure, or the caller's ctx was cancelled before the response arrived.

Common situations: OPENAI_BASE_URL typo or missing scheme (e.g. 'api.openai.com' without https://), offline environment or DNS failure, corporate proxy not configured, context deadline exceeded on long completions, TLS cert issues with self-hosted/proxied endpoints.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/13fd154fe65090e6. Report an issue: GitHub.