{"record":{"id":"7893113e65f4b292","repo":"vxcontrol/pentagi","slug":"failed-to-do-request-w-789311","errorCode":null,"errorMessage":"failed to do request: %w","messagePattern":"failed to do request: %w","errorType":"exception","errorClass":"Retryable","httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/searchers/searxng.go","lineNumber":125,"sourceCode":"\tapiURL.RawQuery = params.Encode()\n\n\tclient, err := system.GetHTTPClient(s.cfg)\n\tif err != nil {\n\t\treturn \"\", Fatal(fmt.Errorf(\"failed to create http client: %w\", err))\n\t}\n\n\tclient.Timeout = s.timeout()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, apiURL.String(), nil)\n\tif err != nil {\n\t\treturn \"\", Fatal(fmt.Errorf(\"failed to create request: %w\", err))\n\t}\n\n\treq.Header.Set(\"User-Agent\", \"PentAGI/1.0\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", Retryable(fmt.Errorf(\"failed to do request: %w\", err), 0)\n\t}\n\tdefer resp.Body.Close()\n\n\treturn s.parseHTTPResponse(resp, query)\n}\n\nfunc (s *searxng) parseHTTPResponse(resp *http.Response, query string) (string, error) {\n\tif resp.StatusCode != http.StatusOK {\n\t\terr := fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode)\n\t\tif resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 {\n\t\t\treturn \"\", Retryable(err, 0)\n\t\t}\n\t\treturn \"\", Fatal(err)\n\t}\n\n\tvar searxngResponse SearxngResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&searxngResponse); err != nil {\n\t\treturn \"\", Fatal(fmt.Errorf(\"failed to decode response body: %w\", err))","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/searchers/searxng.go#L107-L143","documentation":"The HTTP GET to the SearxNG instance failed at transport level (client.Do returned an error). This is wrapped as Retryable(err, 0), meaning the search orchestrator may retry it and/or fall back to other engines. Typical causes: DNS failure, connection refused, TLS handshake failure, or the request context being canceled/timed out (client.Timeout default 30s from SearxngTimeout).","triggerScenarios":"SearxNG container not running or wrong host/port in SEARXNG_URL; network policy blocking container-to-container traffic; TLS certificate error against an HTTPS SearxNG instance; slow SearxNG exceeding the configured SEARXNG_TIMEOUT (default 30s); ctx canceled because the parent flow finished.","commonSituations":"docker-compose service name mismatch in SEARXNG_URL (e.g. http://searx:8080 vs http://searxng:8080); SearxNG crashed/OOMed; self-signed certificate not trusted by the Go client; reverse proxy in front of SearxNG down.","solutions":["Verify the SearxNG instance is up and reachable: curl the SEARXNG_URL from inside the backend container","Correct the hostname/port in SEARXNG_URL (must match the docker-compose service name and port)","Check docker network connectivity and that both containers share the network","If HTTPS, ensure the SearxNG certificate is trusted (custom CA config) or use plain HTTP internally","Increase SEARXNG_TIMEOUT if the instance is slow; the error is Retryable so transient outages self-heal via the fallback chain"],"exampleFix":"// before (docker-compose.yml)\nSEARXNG_URL=http://searx:8080\n# after (docker-compose.yml)\nSEARXNG_URL=http://searxng:8080\n","handlingStrategy":"retry","validationCode":"// preflight reachability check before enabling the engine\nresp, err := http.Head(baseURL)\nif err != nil {\n    log.Printf(\"searxng unreachable, will rely on fallback engines: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"result, err := searxngSearcher.Handle(ctx, req)\nif err != nil && isRetryable(err) {\n    select {\n    case <-ctx.Done():\n        return ctx.Err()\n    case <-time.After(backoff):\n        result, err = searxngSearcher.Handle(ctx, req)\n    }\n}\nif err != nil {\n    result, err = fallbackSearcher.Handle(ctx, req)\n}","preventionTips":["Verify SEARXNG_URL matches the docker-compose service name and exposed port","Confirm both containers share the same Docker network","Use plain HTTP for intra-compose traffic to avoid TLS trust issues","Set SEARXNG_TIMEOUT generously (default 30s) for slow instances and add healthchecks so a dead SearxNG is detected before flows run"],"tags":["network","http","connection","searxng","retryable"],"backgroundTag":"connection-refused","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}