Tencent/WeKnora · error

failed to read response: %w

Error message

failed to read response: %w

What it means

Reading the Tavily response body with io.ReadAll failed after a 200 status. This is rare — typically a connection reset mid-body, truncated transfer, or context cancellation while streaming the response.

Source

Thrown at internal/infrastructure/web_search/tavily.go:98

		return nil, fmt.Errorf("failed to create request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")

	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][Tavily] API returned status %d: %s", resp.StatusCode, string(respBody))
		return nil, fmt.Errorf("tavily API returned status %d: %s", resp.StatusCode, string(respBody))
	}

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

	var respData tavilySearchResponse
	if err := json.Unmarshal(respBody, &respData); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response: %w", err)
	}

	results := make([]*types.WebSearchResult, 0, len(respData.Results))
	for _, item := range respData.Results {
		result := &types.WebSearchResult{
			Title:   item.Title,
			URL:     item.URL,
			Snippet: item.Content,
			Source:  "tavily",
		}
		if includeDate && item.PublishedDate != "" {
			if t, err := time.Parse(time.RFC3339, item.PublishedDate); err == nil {
				result.PublishedAt = &t

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Retry the request — this is usually transient.
  2. Check proxy/load-balancer timeout configurations between the client and Tavily.
  3. Ensure the context deadline exceeds the expected response time; cancel context causes read errors.
  4. Inspect the wrapped error with errors.Is(err, context.Canceled) vs net errors to distinguish cancellation from network issues.
Defensive patterns

Strategy: retry

Validate before calling

// nothing to validate pre-call; ensure context has adequate deadline
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()

Try / catch

results, err := provider.Search(ctx, q, 5, false)
if err != nil {
    if strings.Contains(err.Error(), "failed to read response") && errors.Is(err, context.Canceled) == false {
        return retryWithBackoff(ctx, 3) // transient body-read failure
    }
    return err
}

Prevention

When it happens

Trigger: Calling provider.Search when the TCP connection drops while reading the response body, the server closes the connection early, or the request context is cancelled mid-read.

Common situations: Flaky networks, load balancers/proxies with aggressive idle timeouts, very large response bodies interrupted, container network instability.

Related errors


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