{"record":{"id":"c495eb0535937f15","repo":"micro/go-micro","slug":"failed-to-create-request-w-c495eb","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/gemini/gemini.go","lineNumber":295,"sourceCode":"\tif s.closed {\n\t\treturn nil\n\t}\n\ts.closed = true\n\treturn s.body.Close()\n}\n\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, \"/\") +\n\t\t\"/v1beta/models/\" + p.opts.Model + \":generateContent\"\n\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(\"x-goog-api-key\", 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 geminiResp struct {\n\t\tCandidates []struct {","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/gemini/gemini.go#L277-L313","documentation":"callAPI failed constructing the http.Request for POST /v1beta/models/<model>:generateContent, typically because the composed URL was invalid or the context was already canceled. The wrapped %w error distinguishes url construction issues from context cancellation.","triggerScenarios":"Calling a non-streaming Gemini method with an opts.Model or opts.BaseURL that yields an unparsable URL (spaces, control characters, missing scheme), or with an already-canceled ctx.","commonSituations":"Model name from env containing a newline/trailing space; BaseURL misconfigured for a self-hosted gateway without scheme; parent context canceled before the call executes.","solutions":["Sanitize opts.Model and opts.BaseURL: trim whitespace and confirm BaseURL parses via net/url.Parse with a valid scheme.","If the wrapped error is 'context canceled', audit the caller's context lifecycle and deadlines.","Log the composed URL to spot path-unsafe characters from the model name.","Validate configuration at startup rather than at request time."],"exampleFix":"// before\nprovider, _ := gemini.NewProvider(gemini.WithBaseURL(cfg.Endpoint))\n// after\nu, err := url.Parse(cfg.Endpoint)\nif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") {\n    return fmt.Errorf(\"invalid gemini BaseURL: %q\", cfg.Endpoint)\n}\nprovider, _ := gemini.NewProvider(gemini.WithBaseURL(strings.TrimRight(cfg.Endpoint, \" \")))","handlingStrategy":"validation","validationCode":"u, err := url.Parse(strings.TrimSpace(baseURL))\nif err != nil || u.Host == \"\" || (u.Scheme != \"http\" && u.Scheme != \"https\") {\n    return fmt.Errorf(\"invalid gemini BaseURL: %q\", baseURL)\n}\nif strings.TrimSpace(model) != model || model == \"\" {\n    return fmt.Errorf(\"invalid gemini model: %q\", model)\n}","typeGuard":"func validCallAPIConfig(baseURL, model string) bool {\n    u, err := url.Parse(baseURL)\n    return err == nil && u.Host != \"\" && (u.Scheme == \"http\" || u.Scheme == \"https\") &&\n        model != \"\" && strings.TrimSpace(model) == model\n}","tryCatchPattern":"resp, err := provider.Generate(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create request\") {\n        if ctx.Err() != nil { return fmt.Errorf(\"canceled: %w\", ctx.Err()) }\n        return fmt.Errorf(\"bad provider config (check BaseURL/model): %w\", err)\n    }\n    return err\n}","preventionTips":["Sanitize and validate BaseURL/model at provider construction time","Strip whitespace from all env-derived configuration","Ensure parent contexts are alive when issuing calls"],"tags":["http","url","gemini","request-construction","configuration"],"backgroundTag":"invalid-request-url","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}