{"record":{"id":"9c8556819d034846","repo":"vxcontrol/pentagi","slug":"failed-to-create-search-request-w","errorCode":null,"errorMessage":"failed to create search request: %w","messagePattern":"failed to create search request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/searchers/duckduckgo.go","lineNumber":150,"sourceCode":"// search performs a web search using DuckDuckGo\nfunc (d *duckduckgo) search(ctx context.Context, query string, maxResults int) (string, error) {\n\t// Build form data for POST request\n\tformData := d.buildFormData(query)\n\n\t// Create HTTP client with proper configuration\n\tclient, err := system.GetHTTPClient(d.cfg)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create http client: %w\", err)\n\t}\n\n\tclient.Timeout = duckduckgoTimeout\n\n\t// Execute request with retry logic\n\tvar response *searchResponse\n\tfor attempt := 0; attempt < duckduckgoMaxRetries; attempt++ {\n\t\treq, err := http.NewRequestWithContext(ctx, \"POST\", duckduckgoSearchURL, strings.NewReader(formData))\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to create search request: %w\", err)\n\t\t}\n\n\t\t// Add necessary headers for POST request\n\t\treq.Header.Set(\"User-Agent\", duckduckgoUserAgent)\n\t\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\t\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\")\n\t\treq.Header.Set(\"Accept-Language\", \"en-US,en;q=0.9\")\n\n\t\tresp, err := client.Do(req)\n\t\tif err != nil {\n\t\t\tif attempt == duckduckgoMaxRetries-1 {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to execute search after %d attempts: %w\", duckduckgoMaxRetries, err)\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn \"\", ctx.Err()\n\t\t\tcase <-time.After(time.Second):\n\t\t\t}","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/searchers/duckduckgo.go#L132-L168","documentation":"http.NewRequestWithContext fails while constructing the POST request to the DuckDuckGo HTML endpoint. In net/http this errors only on an unparseable URL or invalid method/ctx-nil combination, so this wrap is a defensive guard around the constant duckduckgoSearchURL. It aborts the search immediately (no retry) and becomes a Fatal engine failure in Handle.","triggerScenarios":"Only when the request URL is malformed or the method string is invalid. Since duckduckgoSearchURL and \"POST\" are compile-time constants, this is practically unreachable unless the URL constant is edited to an invalid value or the code is changed to interpolate a bad URL.","commonSituations":"A developer edits duckduckgoSearchURL and introduces whitespace/typo; refactoring the URL to come from config with a bad value; nil context misuse after refactor.","solutions":["Read the wrapped error: it names the parse problem with the URL; fix the duckduckgoSearchURL constant or its source value.","Assert the URL parses at startup (url.Parse in an init/test) to fail fast after edits.","If the URL became configurable, validate it before passing to NewRequestWithContext."],"exampleFix":"// before\nduckduckgoSearchURL = \"https://duckduckgo.com/ html\"\n// after\nduckduckgoSearchURL = \"https://duckduckgo.com/html/\"","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(duckduckgoSearchURL); err != nil {\n    panic(fmt.Sprintf(\"duckduckgoSearchURL invalid: %v\", err))\n}","typeGuard":null,"tryCatchPattern":"req, err := http.NewRequestWithContext(ctx, \"POST\", duckduckgoSearchURL, strings.NewReader(formData))\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create search request: %w\", err)\n}","preventionTips":["Keep the endpoint URL a validated package-level constant","Add an init-time or unit-test assertion that all searcher endpoint URLs parse","If the URL becomes configurable, validate it in config loading"],"tags":["http","url","go"],"backgroundTag":"malformed-url","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}