{"record":{"id":"ab50573f405929a1","repo":"Tencent/WeKnora","slug":"failed-to-create-request-w-ab5057","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/web_search/duckduckgo.go","lineNumber":80,"sourceCode":"\t}\n\treturn nil, fmt.Errorf(\"duckduckgo API search failed: %w\", apiErr)\n}\n\n// searchHTML performs a web search using DuckDuckGo HTML endpoint\nfunc (p *DuckDuckGoProvider) searchHTML(\n\tctx context.Context,\n\tquery string,\n\tmaxResults int,\n) ([]*types.WebSearchResult, error) {\n\tbaseURL := \"https://html.duckduckgo.com/html/\"\n\tparams := url.Values{}\n\tparams.Set(\"q\", query)\n\tparams.Set(\"kl\", \"cn-zh\")\n\n\treqURL := baseURL + \"?\" + params.Encode()\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", reqURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\treq.Header.Set(\n\t\t\"User-Agent\",\n\t\t\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\",\n\t)\n\n\tcurlCommand := fmt.Sprintf(\n\t\t\"curl -X GET '%s' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'\",\n\t\treq.URL.String(),\n\t)\n\tlogger.Infof(ctx, \"Curl of request: %s\", secutils.SanitizeForLog(curlCommand))\n\n\tresp, err := p.client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to perform request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/web_search/duckduckgo.go#L62-L98","documentation":"http.NewRequestWithContext failed while constructing the DuckDuckGo HTML GET request in searchHTML, and the error is wrapped with \"failed to create request\". This happens before any network I/O, when the request URL cannot be parsed.","triggerScenarios":"baseURL + \"?\" + params.Encode() produces a malformed URL — e.g. query containing characters that break parsing, or an invalid/blank baseURL constant.","commonSituations":"Extremely large or binary-corrupted query strings; baseURL changed to an invalid value; context already canceled at call time.","solutions":["Read the wrapped error to identify the invalid URL part.","URL-encode the query (url.QueryEscape) before placing it in params, and validate baseURL is an absolute https URL.","Ensure the passed ctx is not already canceled."],"exampleFix":"// before\nparams.Set(\"q\", query)\n// after\nparams.Set(\"q\", url.QueryEscape(query))\nif _, err := url.Parse(baseURL); err != nil {\n    return nil, fmt.Errorf(\"invalid baseURL: %w\", err)\n}","handlingStrategy":"validation","validationCode":"escaped := url.QueryEscape(query)\nif escaped == \"\" || len(escaped) > 2000 {\n    return errors.New(\"query missing or too long\")\n}","typeGuard":"func isRequestBuildErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to create request\")\n}","tryCatchPattern":"results, err := ddg.Search(ctx, query, 10, false)\nif isRequestBuildErr(err) {\n    return fmt.Errorf(\"duckduckgo request construction failed (check baseURL/context): %w\", err)\n}","preventionTips":["Always escape query values with url.QueryEscape before building URLs.","Ensure contexts are live (not canceled) before initiating searches.","Unit-test request construction with edge-case inputs (unicode, empty, very long)."],"tags":["http","url","web-search","go"],"backgroundTag":"invalid-request-url","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}