vxcontrol/pentagi · error

failed to create http client: %w

Error message

failed to create http client: %w

What it means

newSearchService returns 'failed to create http client: %w' when system.GetHTTPClient(g.cfg) cannot construct the shared proxy/TLS-aware HTTP client. It is wrapped by Handle into a Fatal error, so Google is skipped for the query. This is a local client-construction failure — no Google request was made.

Source

Thrown at backend/pkg/tools/searchers/google.go:116

	return g.formatResults(resp), nil
}

func (g *google) formatResults(res *customsearch.Search) string {
	var writer strings.Builder
	for i, item := range res.Items {
		writer.WriteString(fmt.Sprintf("# %d. %s\n\n", i+1, item.Title))
		writer.WriteString(fmt.Sprintf("## URL\n%s\n\n", item.Link))
		writer.WriteString(fmt.Sprintf("## Snippet\n\n%s\n\n", item.Snippet))
	}

	return writer.String()
}

func (g *google) newSearchService(ctx context.Context) (*customsearch.Service, error) {
	client, err := system.GetHTTPClient(g.cfg)
	if err != nil {
		return nil, fmt.Errorf("failed to create http client: %w", err)
	}

	// google.golang.org/api normally injects the API key through the HTTP transport it
	// builds itself. But we MUST supply our own proxy/TLS client via WithHTTPClient, and
	// WithHTTPClient takes precedence — it replaces that transport, so option.WithAPIKey
	// is silently dropped and requests go out unauthenticated (HTTP 403 "unregistered
	// caller"). Attach the key ourselves as the `key` query parameter (the documented
	// Custom Search auth) by wrapping the proxy client's transport.
	client.Transport = &googleAPIKeyTransport{
		key:  g.apiKey(),
		base: client.Transport,
	}

	svc, err := customsearch.NewService(ctx, option.WithHTTPClient(client))
	if err != nil {
		return nil, fmt.Errorf("failed to create google search service: %v", err)
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped cause and fix the offending config value (proxy URL, CA cert path)
  2. Validate HTTPS_PROXY/HTTP_PROXY/NO_PROXY and CA bundle env vars in .env and docker-compose.yml
  3. Mount the CA certificate file into the container if a custom CA is required
  4. Test locally: the same GetHTTPClient is used by other engines, so if all engines fail, the problem is shared client config, not Google

Example fix

// before
HTTPS_PROXY=proxy.internal:3128
// after (valid URL with scheme)
HTTPS_PROXY=http://proxy.internal:3128
Defensive patterns

Strategy: validation

Validate before calling

// validate client construction at startup, before any search
if _, err := system.GetHTTPClient(cfg); err != nil {
    log.Fatalf("invalid proxy/TLS config: %v", err)
}

Prevention

When it happens

Trigger: system.GetHTTPClient fails loading proxy configuration or TLS material: malformed HTTPS_PROXY URL, missing/unreadable CA certificate file, or invalid TLS config derived from cfg.

Common situations: HTTPS_PROXY set to an invalid URL in .env/docker-compose; custom CA bundle path wrong or file not mounted into the container; TLS config env vars misformatted after a config refactor.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/6add2253a958fb4d. Report an issue: GitHub.