{"record":{"id":"7690997c94374527","repo":"micro/go-micro","slug":"stream-api-request-failed-w-769099","errorCode":null,"errorMessage":"stream API request failed: %w","messagePattern":"stream API request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/ollama/ollama.go","lineNumber":349,"sourceCode":"\treqBody, err := json.Marshal(apiReq)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal stream request: %w\", err)\n\t}\n\n\tapiURL := strings.TrimRight(p.opts.BaseURL, \"/\") + p.streamPath()\n\thttpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create stream request: %w\", err)\n\t}\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"Accept\", \"text/event-stream\")\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, fmt.Errorf(\"stream API request failed: %w\", err)\n\t}\n\tif httpResp.StatusCode != http.StatusOK {\n\t\tdefer httpResp.Body.Close()\n\t\trespBody, _ := io.ReadAll(httpResp.Body)\n\t\treturn nil, fmt.Errorf(\"stream API error (%s): %s\", httpResp.Status, string(respBody))\n\t}\n\n\treturn &sseStream{body: httpResp.Body, scanner: bufio.NewScanner(httpResp.Body)}, nil\n}\n\n// buildOpenAIMessages converts an ai.Request into the OpenAI chat message format.\nfunc buildOpenAIMessages(req *ai.Request) []map[string]any {\n\tmessages := []map[string]any{}\n\tif req.SystemPrompt != \"\" {\n\t\tmessages = append(messages, map[string]any{\"role\": \"system\", \"content\": req.SystemPrompt})\n\t}\n\tfor _, m := range req.Messages {\n\t\tmessages = append(messages, map[string]any{\"role\": m.Role, \"content\": m.Content})","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/ollama/ollama.go#L331-L367","documentation":"streamOpenAI (used for Ollama Cloud / OpenAI-compatible endpoints) failed to execute the streaming HTTP POST to /v1/chat/completions. The error wraps the transport-level error from http.DefaultClient.Do, so the message contains the underlying net/http cause (DNS, TCP, TLS, timeout, context cancellation). No HTTP response was received at all.","triggerScenarios":"Calling Stream() when isCloud() is true (BaseURL contains ollama.com or cloudOverride set) and the HTTP request fails at the transport layer: server unreachable, connection refused, DNS failure, TLS error, or ctx cancelled before response headers.","commonSituations":"Wrong BaseURL or port, Ollama Cloud API key set but network/VPN blocking ollama.com, local proxy down, request context cancelled/expired mid-request, DNS misconfiguration in containers.","solutions":["Verify BaseURL is reachable: curl -v <BaseURL>/v1/chat/completions from the same host.","Check that ctx is not already cancelled and no overly tight timeout is applied.","Confirm DNS/proxy settings (HTTP_PROXY/HTTPS_PROXY) and that ollama.com is reachable.","Inspect the wrapped %w error for the concrete cause (connection refused vs timeout vs TLS)."],"exampleFix":"// before\np := ai.NewProvider(\"ollama\", ai.WithBaseURL(\"https://ollama.wrong-host.example/v1\"))\n// after\np := ai.NewProvider(\"ollama\", ai.WithBaseURL(\"https://ollama.com/v1\"), ai.WithAPIKey(os.Getenv(\"OLLAMA_API_KEY\")))","handlingStrategy":"retry","validationCode":"u, err := url.Parse(\"https://ollama.com/v1\")\nif err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"invalid base URL: %w\", err)\n}\nconn, err := net.DialTimeout(\"tcp\", u.Hostname()+\":443\", 3*time.Second)\nif err != nil {\n    return fmt.Errorf(\"ollama cloud unreachable: %w\", err)\n}\nconn.Close()\nif ctx.Err() != nil {\n    return ctx.Err()\n}","typeGuard":null,"tryCatchPattern":"stream, err := provider.Stream(ctx, req)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && (errors.Is(err, context.DeadlineExceeded) || isTransient(err)) {\n        // retry with backoff\n    }\n    return fmt.Errorf(\"stream setup failed: %w\", err)\n}","preventionTips":["Health-check the endpoint at startup with a short plain (non-stream) request.","Always pass a context with a sane but generous deadline for long streams.","Log the wrapped error chain with %v/%w so the root cause is visible.","Avoid aggressive proxies/VPNs between the app and ollama.com in production."],"tags":["network","http-client","streaming","ollama-cloud"],"backgroundTag":"http-request-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}