charmbracelet/crush · error
failed to execute search: %w
Error message
failed to execute search: %w
What it means
The HTTP request to DuckDuckGo's lite endpoint failed at transport level (client.Do error), wrapped here. This is a network failure — DNS resolution, TCP connect, TLS, timeout, or proxy error — not a bad response. The deferred body close is never reached since no response exists.
Source
Thrown at internal/agent/tools/search.go:86
var ddgLiteEndpoint = "https://lite.duckduckgo.com/lite/?q="
func searchDuckDuckGo(ctx context.Context, client *http.Client, query string, maxResults int) ([]SearchResult, error) {
if maxResults <= 0 {
maxResults = 10
}
searchURL := ddgLiteEndpoint + url.QueryEscape(query)
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
setRandomizedHeaders(req)
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to execute search: %w", err)
}
defer resp.Body.Close()
// A 202 from DuckDuckGo is the anomaly-challenge interstitial, not a
// result page; report throttling rather than parsing it into an
// empty result set.
if resp.StatusCode == http.StatusAccepted {
return nil, errSearchRateLimited
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("search failed with status code: %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Read the wrapped error to distinguish DNS vs connect vs timeout and fix that layer
- Configure HTTPS_PROXY/HTTP_PROXY if outbound traffic needs a proxy
- Verify DNS and outbound HTTPS (curl -v https://duckduckgo.com/lite) from the same host
- Retry on transient errors; increase client timeout if it fires under load
Example fix
// before
client := &http.Client{} // default, no proxy/timeout tuning
// after
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyFromEnvironment},
Timeout: 30 * time.Second,
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight connectivity check
req, _ := http.NewRequestWithContext(ctx, "HEAD", "https://duckduckgo.com", nil)
if _, err := http.DefaultClient.Do(req); err != nil {
return fmt.Errorf("no outbound connectivity: %w", err)
} Try / catch
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// exponential backoff then retry
}
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) {
// check DNS / proxy configuration
} Prevention
- Configure HTTP(S)_PROXY in sandboxed/corporate environments
- Set a sane client timeout (e.g. 30s)
- Distinguish timeout vs DNS vs connect errors via errors.As
- Cache results to reduce dependence on the network
When it happens
Trigger: client.Do(req) returns an error: no network, DNS failure, connection refused/timeout, TLS interception, or the http.Client's timeout exceeded.
Common situations: Running in an air-gapped/behind-firewall environment; corporate proxy not configured (missing HTTPS_PROXY); DNS blocked for duckduckgo.com; transient network outage; client timeout too small for slow links.
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
- failed to create request: %w
- failed to download from URL: %w
- failed to create request: %w
- failed to fetch URL: %w
- failed to fetch URL: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/db3a50a1d212a6ae.
Report an issue: GitHub.