micro/go-micro · error

failed to create request: %w

Error message

failed to create request: %w

What it means

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".

Source

Thrown at ai/anthropic/anthropic.go:363

}

func usage(input, output int) ai.Usage {
	return ai.Usage{InputTokens: input, OutputTokens: output, TotalTokens: input + output}
}

// callAPI makes an HTTP request to the Anthropic API
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, any, error) {
	// Marshal request
	reqBody, err := json.Marshal(req)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	// Build HTTP request
	apiURL := strings.TrimRight(p.opts.BaseURL, "/") + "/v1/messages"
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("x-api-key", p.opts.APIKey)
	httpReq.Header.Set("anthropic-version", "2023-06-01")

	// Make request
	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}
	defer httpResp.Body.Close()

	// Read response
	respBody, err := io.ReadAll(httpResp.Body)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to read response: %w", err)

View on GitHub (pinned to 24529f1404)

Solutions

  1. Sanitize the base URL: strings.TrimSpace and verify it parses with url.Parse and has an http/https scheme.
  2. Log the fully composed URL and reproduce the failure with url.Parse to get the exact parse error from the wrapped err.
  3. Fix the configuration source (.env quoting, YAML indentation, shell export) that injected invalid characters.

Example fix

// before
baseURL := os.Getenv("ANTHROPIC_BASE_URL")
p, _ := anthropic.New(anthropic.WithBaseURL(baseURL))
// after
baseURL := strings.TrimSpace(os.Getenv("ANTHROPIC_BASE_URL"))
if _, err := url.Parse(baseURL + "/v1/messages"); err != nil { return fmt.Errorf("invalid base URL: %w", err) }
p, _ := anthropic.New(anthropic.WithBaseURL(baseURL))
Defensive patterns

Strategy: validation

Validate before calling

func validAPIURL(base string) bool {
	u, err := url.Parse(strings.TrimSpace(base) + "/v1/messages")
	return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

resp, err := provider.Generate(ctx, prompt)
if err != nil && strings.Contains(err.Error(), "failed to create request") {
	return fmt.Errorf("check ANTHROPIC_BASE_URL formatting: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: Env var ANTHROPIC_BASE_URL with a trailing newline from .env parsing, misconfigured proxy base URL, or copy-pasted URL with embedded whitespace.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/dfa4595d2b444d2e. Report an issue: GitHub.