{"record":{"id":"dfa4595d2b444d2e","repo":"micro/go-micro","slug":"failed-to-create-request-w","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/anthropic/anthropic.go","lineNumber":363,"sourceCode":"}\n\nfunc usage(input, output int) ai.Usage {\n\treturn ai.Usage{InputTokens: input, OutputTokens: output, TotalTokens: input + output}\n}\n\n// callAPI makes an HTTP request to the Anthropic API\nfunc (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, any, error) {\n\t// Marshal request\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\t// Build HTTP request\n\tapiURL := strings.TrimRight(p.opts.BaseURL, \"/\") + \"/v1/messages\"\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\t// Set headers\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"x-api-key\", p.opts.APIKey)\n\thttpReq.Header.Set(\"anthropic-version\", \"2023-06-01\")\n\n\t// Make request\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\t// Read response\n\trespBody, err := io.ReadAll(httpResp.Body)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to read response: %w\", err)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/anthropic/anthropic.go#L345-L381","documentation":"Returned by Provider.callAPI when http.NewRequestWithContext fails to construct the POST request to the Anthropic /v1/messages endpoint. As with the streaming variant, this is almost always a malformed URL produced by concatenating opts.BaseURL with \"/v1/messages\".","triggerScenarios":"opts.BaseURL contains characters invalid in a URL (spaces, newlines, control chars), lacks a scheme, or the ctx is nil/invalid when passed to NewRequestWithContext.","commonSituations":"Env var ANTHROPIC_BASE_URL with a trailing newline from .env parsing, misconfigured proxy base URL, or copy-pasted URL with embedded whitespace.","solutions":["Sanitize the base URL: strings.TrimSpace and verify it parses with url.Parse and has an http/https scheme.","Log the fully composed URL and reproduce the failure with url.Parse to get the exact parse error from the wrapped err.","Fix the configuration source (.env quoting, YAML indentation, shell export) that injected invalid characters."],"exampleFix":"// before\nbaseURL := os.Getenv(\"ANTHROPIC_BASE_URL\")\np, _ := anthropic.New(anthropic.WithBaseURL(baseURL))\n// after\nbaseURL := strings.TrimSpace(os.Getenv(\"ANTHROPIC_BASE_URL\"))\nif _, err := url.Parse(baseURL + \"/v1/messages\"); err != nil { return fmt.Errorf(\"invalid base URL: %w\", err) }\np, _ := anthropic.New(anthropic.WithBaseURL(baseURL))","handlingStrategy":"validation","validationCode":"func validAPIURL(base string) bool {\n\tu, err := url.Parse(strings.TrimSpace(base) + \"/v1/messages\")\n\treturn err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","typeGuard":null,"tryCatchPattern":"resp, err := provider.Generate(ctx, prompt)\nif err != nil && strings.Contains(err.Error(), \"failed to create request\") {\n\treturn fmt.Errorf(\"check ANTHROPIC_BASE_URL formatting: %w\", err)\n}","preventionTips":["Trim all URL config values loaded from env/files","Sanity-check the composed URL at startup, not per-request","Avoid quoting bugs in .env/YAML that inject stray characters"],"tags":["http","url","config","anthropic"],"backgroundTag":"invalid-base-url","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}