{"record":{"id":"f1f3d7d2916601db","repo":"micro/go-micro","slug":"api-request-failed-w-f1f3d7","errorCode":null,"errorMessage":"API request failed: %w","messagePattern":"API request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/ollama/ollama.go","lineNumber":244,"sourceCode":"func (p *Provider) callOpenAI(ctx context.Context, req map[string]any) (*ai.Response, *rawChatMessage, 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, \"/\") + p.chatPath()\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\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\tif p.opts.APIKey != \"\" {\n\t\thttpReq.Header.Set(\"Authorization\", \"Bearer \"+p.opts.APIKey)\n\t}\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, fmt.Errorf(\"API error (%s): %s\", httpResp.Status, string(respBody))\n\t}\n\n\tvar chatResp struct {\n\t\tUsage struct {\n\t\t\tPromptTokens     int `json:\"prompt_tokens\"`\n\t\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\t\tTotalTokens      int `json:\"total_tokens\"`\n\t\t} `json:\"usage\"`\n\t\tChoices []struct {\n\t\t\tMessage struct {\n\t\t\t\tRole      string `json:\"role\"`\n\t\t\t\tContent   string `json:\"content\"`","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/ollama/ollama.go#L226-L262","documentation":"Wraps the transport-level error from http.DefaultClient.Do when POSTing to the Ollama OpenAI-compatible chat endpoint. It means the HTTP request itself failed before a response was received — DNS failure, connection refused, TLS error, or context cancellation/timeout.","triggerScenarios":"http.DefaultClient.Do(httpReq) returns err in callOpenAI (called from generateOpenAI): Ollama server not running, wrong host/port in BaseURL, network unreachable, TLS handshake failure, or ctx cancelled/expired.","commonSituations":"Ollama daemon not started (connection refused on localhost:11434); pointing at a remote Ollama host that is down or firewalled; wrong scheme (https vs http) causing TLS errors; request context deadline exceeded on slow generations.","solutions":["Confirm the Ollama server is running: curl the BaseURL (e.g. http://localhost:11434) before the call","Check BaseURL host/port/scheme match the actual Ollama endpoint","Increase the context timeout — local LLM generation can be slow","Inspect the wrapped error (errors.Unwrap) to distinguish connection-refused, DNS, TLS, and timeout causes"],"exampleFix":"// before\nctx := context.Background()\nresp, err := provider.Generate(ctx, req)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\ndefer cancel()\nresp, err := provider.Generate(ctx, req)\nif err != nil {\n    if urlErr, ok := errors.As(err, &url.Error{}); ok && errors.Is(urlErr.Err, syscall.ECONNREFUSED) {\n        // Ollama not reachable — check daemon\n    }\n}","handlingStrategy":"retry","validationCode":"// reachability check before calling\nconn, err := net.DialTimeout(\"tcp\", \"localhost:11434\", 2*time.Second)\nif err != nil {\n    return fmt.Errorf(\"ollama server not reachable: %w\", err)\n}\nconn.Close()","typeGuard":"func isConnectionRefused(err error) bool {\n    var urlErr *url.Error\n    return errors.As(err, &urlErr) && errors.Is(urlErr.Err, syscall.ECONNREFUSED)\n}","tryCatchPattern":"resp, err := provider.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) {\n            // increase timeout / retry\n        } else if errors.Is(urlErr.Err, syscall.ECONNREFUSED) {\n            // start ollama serve\n        }\n    }\n    return err\n}","preventionTips":["Start/health-check the Ollama daemon before calls","Use generous timeouts for local LLM inference","Verify BaseURL host/port/scheme per environment","Wrap context cancellation with deadlines matching expected latency"],"tags":["network","connection","timeout","ollama"],"backgroundTag":"connection-refused","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}