vxcontrol/pentagi · error · Retryable
failed to do request: %v
Error message
failed to do request: %v
What it means
traversaal.search returns a Retryable error 'failed to do request: %v' when client.Do(req) fails — the HTTP round trip itself did not complete: DNS failure, connection refused/reset, TLS handshake error, or context cancellation/timeout. It is classified Retryable so the orchestrator may retry or fall back to another engine.
Source
Thrown at backend/pkg/tools/searchers/traversaal.go:97
}{
Query: query,
})
if err != nil {
return "", Fatal(fmt.Errorf("failed to marshal request body: %v", err))
}
req, err := http.NewRequest(http.MethodPost, traversaalURL, bytes.NewBuffer(reqBody))
if err != nil {
return "", Fatal(fmt.Errorf("failed to build request: %v", err))
}
req = req.WithContext(ctx)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", t.apiKey())
resp, err := client.Do(req)
if err != nil {
return "", Retryable(fmt.Errorf("failed to do request: %v", err), 0)
}
defer resp.Body.Close()
return t.parseHTTPResponse(resp)
}
func (t *traversaal) parseHTTPResponse(resp *http.Response) (string, error) {
if resp.StatusCode != http.StatusOK {
err := fmt.Errorf("unexpected status code: %d", resp.StatusCode)
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 {
return "", Retryable(err, 0)
}
return "", Fatal(err)
}
var respBody struct {
Data traversaalSearchResult `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {View on GitHub (pinned to ea665308ba)
Solutions
- Check network egress/DNS from the backend container (e.g. curl the Traversaal endpoint from inside).
- Inspect the wrapped error: 'context deadline exceeded' means raise the caller timeout; 'connection refused' means egress/proxy blocking.
- Configure a valid HTTP(S) proxy or add the proxy CA to the trust store if traffic is intercepted.
- Rely on Retryable classification to fall back to another engine in the web_search fallbackStrategy.
Example fix
// before: unbounded caller context ctx := context.Background() // after: bounded, cancellation-aware context ctx, cancel := context.WithTimeout(ctx, 15*time.Second) defer cancel()
Defensive patterns
Strategy: retry
Validate before calling
if err := ctx.Err(); err != nil {
return fmt.Errorf("context already done, skipping search: %w", err)
} Type guard
func isRetryable(err error) bool {
var r *searchers.RetryableError
return errors.As(err, &r)
} Try / catch
result, err := traversaalSearcher.Handle(ctx, req)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return "", fmt.Errorf("traversaal timed out; raise caller timeout")
}
if isRetryable(err) {
return fallbackEngine.Handle(ctx, req)
}
return "", err
} Prevention
- Verify outbound DNS and egress from the deployment container
- Use bounded contexts with timeouts appropriate for remote search APIs
- Trust proxy/TLS configuration before enabling remote searchers
When it happens
Trigger: client.Do(req) returns err in search() — network unreachable, DNS resolution failure for the Traversaal host, TLS errors, or the request context (ctx) was canceled/timed out by the caller.
Common situations: No outbound internet/DNS in the Docker container; corporate proxy blocking api.traversaal.ai; ctx deadline exceeded under slow agent pipelines; TLS interception with unknown CA.
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 execute search after %d attempts: %w
- failed to send request: %w
- there are temporarily offline for maintenance. please try ag
- image download stream processing failed: %w
- failed to read response body: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/9db0e43d39e64717.
Report an issue: GitHub.