{"id":"de6d2236d793dd62","repo":"gohugoio/hugo","slug":"failed-to-parse-url-for-resource-s-w","errorCode":null,"errorMessage":"failed to parse URL for resource %s: %w","messagePattern":"failed to parse URL for resource (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/resource_factories/create/remote.go","lineNumber":198,"sourceCode":"\t\t\t\tif time.Since(lastChange) < 10*time.Second {\n\t\t\t\t\t// The user is typing, check more often.\n\t\t\t\t\treturn 0, nil\n\t\t\t\t}\n\n\t\t\t\t// Increase the interval to avoid hammering the server.\n\t\t\t\tinterval += 1 * time.Second\n\n\t\t\t\treturn interval, nil\n\t\t\t},\n\t\t})\n}\n\n// FromRemote expects one or n-parts of a URL to a resource\n// If you provide multiple parts they will be joined together to the final URL.\nfunc (c *Client) FromRemote(uri string, optionsm map[string]any) (resource.Resource, error) {\n\trURL, err := url.Parse(uri)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse URL for resource %s: %w\", uri, err)\n\t}\n\n\tmethod := \"GET\"\n\tif s, _, ok := hmaps.LookupEqualFold(optionsm, \"method\"); ok {\n\t\tmethod = strings.ToUpper(s.(string))\n\t}\n\tisHeadMethod := method == \"HEAD\"\n\n\toptionsm = maps.Clone(optionsm)\n\n\t// Extract timeout before computing cache keys: it only affects fetch behaviour,\n\t// not the cached content, so it must not influence the cache key.\n\tvar perRequestTimeout time.Duration\n\tif v, k, ok := hmaps.LookupEqualFold(optionsm, \"timeout\"); ok {\n\t\td, err := cast.ToDurationE(v)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid timeout for resource %s: %w\", uri, err)\n\t\t}","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/resources/resource_factories/create/remote.go#L180-L216","documentation":"`resources.GetRemote` (Client.FromRemote) first parses the given URI with `url.Parse`. If the string is not a syntactically valid URL, Hugo fails fast with this wrapped parse error rather than attempting a request. Note that `url.Parse` is lenient, so this usually means genuinely malformed input like invalid control characters or bad percent-encoding.","triggerScenarios":"Calling `resources.GetRemote $url` in a template where `$url` contains invalid characters (spaces, newlines, unescaped `%` sequences like `%zz`, control chars), or where multiple URL parts were joined/interpolated incorrectly (e.g. `printf` with stray whitespace from front matter).","commonSituations":"URLs read from front matter or data files with trailing newlines/spaces, hand-built query strings with unencoded values, CSV/JSON data containing malformed URLs, or template string concatenation inserting a literal `\\n`.","solutions":["Trim and validate the URL before use: `{{ $u := trim $url \" \\n\" }}`.","Properly encode query parameters (e.g. `querify` or `urlquery`) instead of concatenating raw values.","Print the exact string passed (`warnf \"url=%q\" $url`) to spot hidden whitespace or bad percent-escapes in the data source."],"exampleFix":"{{/* before */}}\n{{ $r := resources.GetRemote (printf \"%s?q=%s\" .Params.api .Params.query) }}\n{{/* after */}}\n{{ $u := printf \"%s?%s\" (trim .Params.api \" \\n\") (querify \"q\" .Params.query) }}\n{{ $r := resources.GetRemote $u }}","handlingStrategy":"validation","validationCode":"{{ $url := .Params.remote_url }}\n{{ $u := urls.Parse $url }}\n{{ if or (not $u.Scheme) (not $u.Host) }}\n  {{ errorf \"invalid remote resource URL: %q\" $url }}\n{{ end }}\n{{ $r := resources.GetRemote $url }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate URLs from front matter/data files with urls.Parse before resources.GetRemote","URL-encode query parameters and spaces; raw user strings often contain illegal characters","Require absolute URLs with an explicit https scheme in content that feeds GetRemote"],"tags":["hugo","get-remote","url-parsing","templates"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}