{"record":{"id":"bbca22ce9ed9507c","repo":"crowdsecurity/crowdsec","slug":"failed-to-build-request-w","errorCode":null,"errorMessage":"failed to build request: %w","messagePattern":"failed to build request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cwhub/download.go","lineNumber":92,"sourceCode":"\t\tWithLogger(logger.WithField(\"url\", url)).\n\t\tBeforeRequest(func(_ *http.Request) {\n\t\t\tfmt.Fprintln(os.Stdout, \"Downloading \" + destPath)\n\t\t}).\n\t\tDownload(ctx, url.String())\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn downloaded, nil\n}\n\n// FetchContent downloads the content to the specified path, through a temporary file\n// to avoid partial downloads.\n// If the hash does not match, it will not overwrite and log a warning.\nfunc (d *Downloader) FetchContent(ctx context.Context, remotePath, destPath, wantHash string, logger *logrus.Logger) (downloaded bool, url string, err error) {\n\tu, err := d.urlTo(remotePath)\n\tif err != nil {\n\t\treturn false, \"\", fmt.Errorf(\"failed to build request: %w\", err)\n\t}\n\n\tdownloaded, err = downloader.\n\t\tNew().\n\t\tWithHTTPClient(HubClient).\n\t\tToFile(destPath).\n\t\tWithETagFn(downloader.SHA256).\n\t\tWithMakeDirs(true).\n\t\tWithLogger(logger.WithField(\"url\", url)).\n\t\tCompareContent().\n\t\tVerifyHash(\"sha256\", wantHash).\n\t\tDownload(ctx, u.String())\n\n\tvar hasherr downloader.HashMismatchError\n\n\tswitch {\n\tcase errors.As(err, &hasherr):\n\t\tlogger.Warnf(\"%s. The index file is outdated, please run 'cscli hub update' and try again\", err.Error())","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/cwhub/download.go#L74-L110","documentation":"FetchContent wraps the error from Downloader.urlTo when building the URL for a hub content file fails. Like the index variant, this is a request-construction failure before any network I/O, with the root cause preserved via %w.","triggerScenarios":"Calling Downloader.FetchContent with a remotePath that, combined with the downloader base URL, fails urlTo — typically because the downloader's base URL is empty or invalid.","commonSituations":"Hub URL unset in configuration, corrupted config after upgrade, or programmatically constructing a Downloader without setting its base URL.","solutions":["Verify the hub api_url in the crowdsec configuration is a valid URL","Re-run `cscli hub update` after fixing the config","If constructing a Downloader in code, ensure the base URL field is populated before calling FetchContent"],"exampleFix":"// before\nd := &Downloader{} // base URL never set\n_, _, err := d.FetchContent(ctx, path, dest, hash, logger)\n// after\nd, err := NewDownloader(hubURL, \"\")\nif err != nil { return err }\n_, _, err = d.FetchContent(ctx, path, dest, hash, logger)","handlingStrategy":"try-catch","validationCode":"if u, err := url.Parse(cfg.HubAPIURL); err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"hub api_url %q is not a valid absolute URL\", cfg.HubAPIURL)\n}","typeGuard":null,"tryCatchPattern":"downloaded, _, err := d.FetchContent(ctx, remote, dest, hash, logger)\nif err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) {\n        logger.Errorf(\"cannot build hub request: %v — check hub URL config\", err)\n        return\n    }\n    return err\n}","preventionTips":["Configure the hub URL explicitly and validate it at startup","Never construct a Downloader with an empty base URL","Test hub connectivity with `cscli hub update` after config edits"],"tags":["network","url","config","hub"],"backgroundTag":"invalid-url-format","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}