Tencent/WeKnora · error
failed to execute Exa request: %w
Error message
failed to execute Exa request: %w
What it means
Wraps errors from p.client.Do(req) when the HTTP round-trip to the Exa API fails before a response is returned. Causes include DNS failures, unreachable host, TLS problems, client timeout, or context cancellation during the request.
Source
Thrown at internal/infrastructure/web_search/exa.go:97
Contents: exaContents{
Highlights: true,
Text: p.includeText,
},
})
if err != nil {
return nil, fmt.Errorf("failed to marshal Exa request: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, p.baseURL, bytes.NewReader(bodyBytes))
if err != nil {
return nil, fmt.Errorf("failed to create Exa request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", p.apiKey)
logger.Infof(ctx, "[WebSearch][Exa] query=%q maxResults=%d url=%s", query, maxResults, p.baseURL)
resp, err := p.client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to execute Exa request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(io.LimitReader(resp.Body, maxExaResponseBytes))
if err != nil {
return nil, fmt.Errorf("failed to read Exa response: %w", err)
}
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
logger.Warnf(ctx, "[WebSearch][Exa] API returned status %d: %s", resp.StatusCode, string(body))
return nil, fmt.Errorf("exa API returned status %d: %s", resp.StatusCode, string(body))
}
var data exaSearchResponse
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("failed to unmarshal Exa response: %w", err)
}
if data.Error != "" {
return nil, fmt.Errorf("exa API error: %s", data.Error)
}View on GitHub (pinned to 988cbb0330)
Solutions
- Confirm outbound connectivity to api.exa.ai:443 from the deployment
- Check/fix the proxyURL in provider parameters
- Increase defaultExaTimeout if large searches time out
- Add bounded retry with backoff for transient failures
- Inspect the unwrapped *url.Error for timeout vs connection specifics
Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", "api.exa.ai:443", 3*time.Second)
if err != nil {
return fmt.Errorf("no egress to api.exa.ai: %w", err)
}
conn.Close() Try / catch
results, err := provider.Search(ctx, query, 10, false)
if err != nil {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() || errors.Is(err, context.DeadlineExceeded) {
return retryWithBackoff(ctx, query)
}
return fallbackProvider.Search(ctx, query, 10, false)
} Prevention
- Allow-list api.exa.ai in firewall/egress rules
- Verify proxy settings with a smoke request at startup
- Size the client timeout to expected worst-case search latency
- Retry idempotent searches with exponential backoff
When it happens
Trigger: Calling Search when the network cannot reach api.exa.ai, the configured proxy is down or wrong, the client timeout (defaultExaTimeout) expires, or ctx is canceled mid-request.
Common situations: No egress to api.exa.ai from a private cluster, invalid proxyURL parameter, firewall blocking the domain, slow Exa responses exceeding the client timeout, revoked DNS in rotating environments.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/910a7e3faf214f33.
Report an issue: GitHub.