Tencent/WeKnora · error

failed to marshal request: %w

Error message

failed to marshal request: %w

What it means

json.Marshal failed while serializing the tavilySearchRequest struct to a request body. This is nearly impossible with the fixed struct (string/int fields), so when it occurs it signals a programming-level issue such as an unsupported field type added to the request struct or a corrupted value (e.g. NaN in a float field) — not a runtime/user problem.

Source

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

	ctx context.Context,
	query string,
	maxResults int,
	includeDate bool,
) ([]*types.WebSearchResult, error) {
	if len(query) == 0 {
		return nil, fmt.Errorf("query is empty")
	}
	logger.Infof(ctx, "[WebSearch][Tavily] query=%q maxResults=%d url=%s", query, maxResults, p.baseURL)

	reqBody := tavilySearchRequest{
		APIKey:     p.apiKey,
		Query:      query,
		MaxResults: maxResults,
	}

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

	req, err := http.NewRequestWithContext(ctx, "POST", p.baseURL, bytes.NewReader(bodyBytes))
	if err != nil {
		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))

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Inspect the wrapped error for the offending field/type reported by encoding/json
  2. Remove or fix unsupported field types in the request struct (no chan/func/cycles; sanitize NaN floats before marshaling)
  3. If upstream data may contain invalid floats, sanitize or zero them before constructing reqBody
  4. Add a unit test marshaling the request struct to catch regressions

Example fix

// before
reqBody := tavilySearchRequest{..., Score: math.NaN()}
// after
score := computedScore
if math.IsNaN(score) || math.IsInf(score, 0) {
    score = 0
}
reqBody := tavilySearchRequest{..., Score: score}
Defensive patterns

Strategy: try-catch

Try / catch

bodyBytes, err := json.Marshal(reqBody)
if err != nil {
    // log the offending field; this indicates a struct/type bug, not transient failure
    logger.Errorf(ctx, "tavily request marshal failed: %v", err)
    return nil, err
}

Prevention

When it happens

Trigger: A custom/extended tavilySearchRequest containing a type json.Marshal cannot encode (chan, func, circular reference, NaN/Inf float); the shipped struct cannot realistically trigger this.

Common situations: After modifying the request struct to add fields of unsupported types; passing through a struct with invalid float values from upstream data.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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