{"record":{"id":"a5f1d7ee951f573a","repo":"micro/go-micro","slug":"api-request-failed-w-a5f1d7","errorCode":null,"errorMessage":"API request failed: %w","messagePattern":"API request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/together/together.go","lineNumber":175,"sourceCode":"\nfunc (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, map[string]any, error) {\n\treqBody, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to marshal request: %w\", err)\n\t}\n\n\tapiURL := strings.TrimRight(p.opts.BaseURL, \"/\") + \"/v1/chat/completions\"\n\thttpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"Authorization\", \"Bearer \"+p.opts.APIKey)\n\n\thttpResp, err := http.DefaultClient.Do(httpReq)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"API request failed: %w\", err)\n\t}\n\tdefer httpResp.Body.Close()\n\n\trespBody, _ := io.ReadAll(httpResp.Body)\n\tif httpResp.StatusCode != http.StatusOK {\n\t\treturn nil, nil, ai.NewHTTPError(httpResp, respBody)\n\t}\n\n\tvar chatResp struct {\n\t\tChoices []struct {\n\t\t\tMessage struct {\n\t\t\t\tContent   string `json:\"content\"`\n\t\t\t\tToolCalls []struct {\n\t\t\t\t\tID       string `json:\"id\"`\n\t\t\t\t\tFunction struct {\n\t\t\t\t\t\tName      string `json:\"name\"`\n\t\t\t\t\t\tArguments string `json:\"arguments\"`\n\t\t\t\t\t} `json:\"function\"`","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/together/together.go#L157-L193","documentation":"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.","triggerScenarios":"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.","commonSituations":"Missing or wrong TOGETHER_API_BASE config, offline CI environments, corporate proxies/firewalls, request context canceled by an upstream timeout, or transient network blips.","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"],"exampleFix":"// before\nctx := context.Background()\nresp, err := p.Generate(ctx, req)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\nresp, err := p.Generate(ctx, req)\nif err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) && urlErr.Timeout() {\n        // retry with backoff\n    }\n}","handlingStrategy":"retry","validationCode":"u, err := url.Parse(baseURL)\nif err != nil || u.Scheme != \"https\" {\n    return fmt.Errorf(\"invalid Together BaseURL: %s\", baseURL)\n}\n// optionally: net.DialTimeout to pre-check reachability","typeGuard":null,"tryCatchPattern":"resp, err := p.Generate(ctx, req)\nif err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) {\n        if errors.Is(urlErr.Err, context.DeadlineExceeded) { /* timeout: retry */ }\n        else { /* network: check connectivity/proxy */ }\n    }\n}","preventionTips":["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"],"tags":["http","network","ai-provider","together"],"backgroundTag":"http-request-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}