Tencent/WeKnora · error

failed to create request: %w

Error message

failed to create request: %w

What it means

KeenableProvider.Search failed to construct the outbound http.Request via http.NewRequestWithContext for its POST to baseURL+path. This wraps errors such as an invalid URL (unsupported scheme, unparseable endpoint) or a nil/invalid context.

Source

Thrown at internal/infrastructure/web_search/keenable.go:89

		maxResults = defaultKeenableResults
	}

	// Keyless by default; a configured key switches to the authenticated path.
	path := "/v1/search/public"
	if p.apiKey != "" {
		path = "/v1/search"
	}
	endpoint := p.baseURL + path
	logger.Infof(ctx, "[WebSearch][Keenable] query=%q maxResults=%d url=%s", query, maxResults, endpoint)

	bodyBytes, err := json.Marshal(keenableSearchRequest{Query: query, Mode: "pro"})
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	req, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewReader(bodyBytes))
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("X-Keenable-Title", keenableTitle)
	if p.apiKey != "" {
		req.Header.Set("X-API-Key", p.apiKey)
	}

	resp, err := p.client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to execute request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		respBody, _ := io.ReadAll(resp.Body)
		logger.Warnf(ctx, "[WebSearch][Keenable] API returned status %d: %s", resp.StatusCode, string(respBody))
		return nil, fmt.Errorf("keenable API returned status %d: %s", resp.StatusCode, string(respBody))

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Log the full endpoint URL (it is already in the preceding log line) and validate the scheme is http/https.
  2. Fix the configured base URL — prepend https:// and trim whitespace/newlines.
  3. Ensure a non-nil context.Context is passed into Search.
  4. Add URL parsing validation at provider construction time to fail early.

Example fix

// before
baseURL: cfg.KeenableURL // "keenable.example.com"
// after
u, err := url.Parse(cfg.KeenableURL)
if err != nil || u.Scheme == "" {
    return nil, fmt.Errorf("invalid keenable URL: %q", cfg.KeenableURL)
}
baseURL: strings.TrimRight(cfg.KeenableURL, "/"),
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(cfg.KeenableBaseURL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
    return errors.New("invalid keenable base URL: must be absolute http(s) URL")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to create request") {
    log.Errorf("keenable endpoint URL invalid: %v", err)
    return nil, fmt.Errorf("check keenable base URL configuration: %w", err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext returns an error — typically because baseURL is malformed (missing scheme, invalid characters, bad URL) or ctx is nil.

Common situations: Misconfigured keenable base URL in config (e.g. 'keenable.example.com' without https://); stray whitespace or newline in configured URL; context constructed incorrectly and passed as nil.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/cb3384231249a596. Report an issue: GitHub.