{"record":{"id":"de53322fa115c3a7","repo":"charmbracelet/crush","slug":"failed-to-create-request-w-de5332","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/fetch_helpers.go","lineNumber":28,"sourceCode":"\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\tmd \"github.com/JohannesKaufmann/html-to-markdown\"\n\t\"golang.org/x/net/html\"\n)\n\n// BrowserUserAgent is a realistic browser User-Agent for better compatibility.\nconst BrowserUserAgent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\"\n\nvar multipleNewlinesRe = regexp.MustCompile(`\\n{3,}`)\n\n// FetchURLAndConvert fetches a URL and converts HTML content to markdown.\nfunc FetchURLAndConvert(ctx context.Context, client *http.Client, url string) (string, error) {\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\t// Use realistic browser headers for better compatibility.\n\treq.Header.Set(\"User-Agent\", BrowserUserAgent)\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"en-US,en;q=0.5\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to fetch URL: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"request failed with status code: %d\", resp.StatusCode)\n\t}\n\n\tmaxSize := int64(5 * 1024 * 1024) // 5MB","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/fetch_helpers.go#L10-L46","documentation":"http.NewRequestWithContext failed to parse the given URL into a valid HTTP GET request. This library surfaces the parse error wrapped as 'failed to create request'. It is thrown before any network I/O occurs, so it is purely a client-side input validation failure.","triggerScenarios":"FetchURLAndConvert (and thus the fetch tool) is called with a URL that has an unsupported scheme (not http/https, e.g. 'ftp://'), contains invalid characters (spaces, unescaped control chars), or is otherwise unparsable by net/url.","commonSituations":"The LLM passes a URL without a scheme ('example.com'), with embedded spaces, or a file:// scheme; malformed percent-encoding; user-supplied URLs from chat input not validated upstream.","solutions":["Validate the URL with url.ParseRequestURI before calling and require http:// or https:// scheme","Trim whitespace and reject/pre-encode URLs containing spaces or control characters","Return a clearer tool error to the model telling it the URL format is invalid","Prepend https:// if the scheme is missing, when appropriate"],"exampleFix":"// before\nreq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create request: %w\", err)\n}\n// after\nu, perr := url.Parse(strings.TrimSpace(url))\nif perr != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") {\n    return \"\", fmt.Errorf(\"invalid or unsupported URL: %q\", url)\n}\nreq, err := http.NewRequestWithContext(ctx, \"GET\", u.String(), nil)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create request: %w\", err)\n}","handlingStrategy":"validation","validationCode":"u, err := url.ParseRequestURI(strings.TrimSpace(rawURL))\nif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") {\n    return fmt.Errorf(\"URL must be absolute http(s): %q\", rawURL)\n}","typeGuard":"null","tryCatchPattern":"req, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create request: %w\", err)\n}","preventionTips":["Always require a scheme (http/https) on user/model-supplied URLs","Trim whitespace and reject control characters before parsing","Use url.ParseRequestURI rather than url.Parse for request targets","Surface a clear invalid-URL message back to the caller/LLM"],"tags":["url","validation","http"],"backgroundTag":"invalid-url","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}