micro/go-micro · error
API request failed: %w
Error message
API request failed: %w
What it means
This error wraps any transport-level failure from the HTTP POST to the Together.ai chat-completions endpoint (http.DefaultClient.Do in callAPI). The library throws it when the request never completes at the network layer — DNS failure, refused connection, TLS error, timeout, or canceled context — before any HTTP status is examined. The original *url.Error is wrapped with %w so errors.Is/As still work.
Source
Thrown at ai/together/together.go:175
func (p *Provider) callAPI(ctx context.Context, 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 {
return nil, nil, ai.NewHTTPError(httpResp, respBody)
}
var chatResp struct {
Choices []struct {
Message struct {
Content string `json:"content"`
ToolCalls []struct {
ID string `json:"id"`
Function struct {
Name string `json:"name"`
Arguments string `json:"arguments"`
} `json:"function"`View on GitHub (pinned to 24529f1404)
Solutions
- Check p.opts.BaseURL is a valid reachable https://api.together.xyz URL
- Verify network/DNS/proxy connectivity from the host (curl the BaseURL)
- Use errors.As(err, &urlErr) or check context.DeadlineExceeded to distinguish timeouts; add retry with backoff for transient failures
- Ensure the context passed to Generate has an adequate deadline
Example fix
// before
ctx := context.Background()
resp, err := p.Generate(ctx, req)
// after
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
resp, err := p.Generate(ctx, req)
if err != nil {
var urlErr *url.Error
if errors.As(err, &urlErr) && urlErr.Timeout() {
// retry with backoff
}
} Defensive patterns
Strategy: retry
Validate before calling
u, err := url.Parse(baseURL)
if err != nil || u.Scheme != "https" {
return fmt.Errorf("invalid Together BaseURL: %s", baseURL)
}
// optionally: net.DialTimeout to pre-check reachability Try / catch
resp, err := p.Generate(ctx, req)
if err != nil {
var urlErr *url.Error
if errors.As(err, &urlErr) {
if errors.Is(urlErr.Err, context.DeadlineExceeded) { /* timeout: retry */ }
else { /* network: check connectivity/proxy */ }
}
} Prevention
- Set explicit timeouts on the request context
- Validate BaseURL at startup
- Add exponential-backoff retry for transient network errors
- Test egress/proxy settings in CI
When it happens
Trigger: Calling Provider.Generate or Generate with tools when the Together API host is unreachable: invalid BaseURL, no network/DNS, proxy blocking egress, context deadline exceeded, or TLS handshake failure.
Common situations: Missing or wrong TOGETHER_API_BASE config, offline CI environments, corporate proxies/firewalls, request context canceled by an upstream timeout, or transient network blips.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- API error: nil response
- failed request
- stream API request failed: %w
- API request failed: %w
- failed to read response: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/a5f1d7ee951f573a.
Report an issue: GitHub.