siyuan-note/siyuan · error
web search failed: %s
Error message
web search failed: %s
What it means
Returned at websearch.go:83 when httpclient.NewBrowserRequest().Post(exaURL) fails at the transport layer before any response body is available. exaURL defaults to https://mcp.exa.ai/mcp (websearch.go:31), appended with ?exaApiKey=... when a key is supplied (websearch.go:62-64). An empty key still issues the request, just unauthenticated. The %s is the underlying transport error.
Source
Thrown at kernel/util/websearch.go:83
reqBody := mcpRequest{
JSONRPC: "2.0",
ID: 1,
Method: "tools/call",
Params: mcpParams{
Name: "web_search_exa",
Arguments: map[string]any{
"query": query,
"type": "auto",
"numResults": 8,
"livecrawl": "fallback",
},
},
}
resp, err := httpclient.NewBrowserRequest().SetHeader("Accept", "application/json, text/event-stream").SetBody(reqBody).Post(exaURL)
if err != nil {
return "", errors.New("web search failed: " + err.Error())
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", errors.New("web search read response failed: " + err.Error())
}
body := string(bodyBytes)
preview := body
if len(preview) > 500 {
preview = body[:500]
}
logging.LogInfof("websearch response: status=%d, len=%d, preview=%s", resp.StatusCode, len(body), preview)
text := parseMcpResponse(body)
if text == "" {
return "No search results found. Please try a different query.", nilView on GitHub (pinned to 251596fc0d)
Solutions
- Confirm the host is reachable from the SiYuan host: `curl -I https://mcp.exa.ai/mcp`.
- Verify internet connectivity and DNS for mcp.exa.ai.
- Check/correct HTTP_PROXY / HTTPS_PROXY env vars.
- Retry once for transient network blips.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm the Exa MCP host is reachable before issuing the search.
func exaReachable() error {
if _, err := net.LookupHost("mcp.exa.ai"); err != nil {
return fmt.Errorf("dns: %w", err)
}
return nil
} Type guard
func isWebSearchFailed(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "web search failed:")
} Try / catch
out, err := util.WebSearch(q, key)
if err != nil && isWebSearchFailed(err) {
// transport-level: back off and retry once
out, err = util.WebSearch(q, key)
} Prevention
- Verify mcp.exa.ai is reachable from the host (curl) before relying on web search.
- Keep proxy env vars correct; Exa is an external HTTPS endpoint.
- Treat web-search-failed as transient and retry once with backoff.
When it happens
Trigger: Calling util.WebSearch(query, key) with no network, mcp.exa.ai unresolvable, TLS handshake failure, proxy pointing at a dead upstream, or an egress firewall blocking the Exa host.
Common situations: Air-gapped/offline host, corporate firewall blocking mcp.exa.ai, broken HTTP_PROXY, captive portal intercepting TLS, IPv6 connectivity problems.
Related errors
- web search read response failed: %s
- tools/list returned an empty response
- discover OAuth authorization server: %w
- register OAuth client: %w
- OAuth protected resource metadata not found
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a652391171e3ab30.
Report an issue: GitHub.