micro/go-micro · error

API request failed: %w

Error message

API request failed: %w

What it means

callAPI in the AtlasCloud provider wraps any error returned by http.DefaultClient.Do when POSTing a chat-completion request. It means the HTTP round trip itself failed — no response was received from the server. This library throws it so the underlying transport error (DNS, TLS, timeout, connection reset) is preserved via %w for errors.Is/As inspection.

Source

Thrown at ai/atlascloud/atlascloud.go:442

func (p *Provider) callAPI(ctx context.Context, phase string, req map[string]any) (*ai.Response, map[string]any, error) {
	reqBody, err := json.Marshal(req)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
	}

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

	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)

	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}
	defer httpResp.Body.Close()

	respBody, _ := io.ReadAll(httpResp.Body)
	if httpResp.StatusCode != http.StatusOK {
		retryAfter := time.Duration(0)
		var retryErr interface{ RetryAfter() time.Duration }
		if errors.As(ai.NewHTTPError(httpResp, respBody), &retryErr) {
			retryAfter = retryErr.RetryAfter()
		}
		return nil, nil, &atlascloudAPIError{Status: httpResp.Status, Code: httpResp.StatusCode, Retry: retryAfter, Phase: phase, Summary: atlascloudRequestSummary(req), Body: string(respBody)}
	}

	var chatResp struct {
		Choices []struct {
			Message struct {
				Content   string          `json:"content"`
				ToolCalls []atlasToolCall `json:"tool_calls"`

View on GitHub (pinned to 24529f1404)

Solutions

  1. Verify p.opts.BaseURL is a correct, reachable URL (curl -v $BASEURL/chat/completions) and includes the https:// scheme.
  2. Check basic connectivity/DNS from the host: ping or curl the API host; check proxy env vars (HTTP_PROXY/HTTPS_PROXY).
  3. Inspect the wrapped error with errors.Is(err, context.DeadlineExceeded) / net.Error.Timeout() and increase the http.Client timeout or extend the context deadline for long completions.
  4. Retry with exponential backoff for transient network errors; check ctx cancellation if requests are being aborted.

Example fix

// before
resp, err := http.DefaultClient.Do(req)
// after
client := &http.Client{Timeout: 120 * time.Second}
resp, err := client.Do(req)
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(baseURL)
if err != nil || u.Host == "" {
    return fmt.Errorf("invalid AtlasCloud BaseURL: %v", err)
}
if _, err := net.LookupHost(u.Hostname()); err != nil {
    return fmt.Errorf("cannot resolve AtlasCloud host: %w", err)
}

Try / catch

resp, err := provider.Generate(ctx, req)
if err != nil {
    var nerr net.Error
    if errors.As(err, &nerr) && nerr.Timeout() {
        // retry with backoff / larger timeout
    }
    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
        // respect cancellation; do not blind-retry
    }
    return fmt.Errorf("atlascloud chat request failed: %w", err)
}

Prevention

When it happens

Trigger: Generate -> callAPI issues http.NewRequestWithContext and calls http.DefaultClient.Do(httpReq); any non-nil error from Do (DNS failure, connection refused, TLS handshake failure, context deadline exceeded while awaiting the response, request cancellation) triggers this wrap.

Common situations: Wrong or unreachable BaseURL (typo, missing scheme, private endpoint), no network/DNS in the environment, corporate proxy blocking the host, very slow model responses exceeding the client timeout causing context deadline, or the caller's ctx being cancelled mid-request.

Related errors


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