{"record":{"id":"27a9478a59aa668a","repo":"kubernetes/kops","slug":"unable-to-parse-assetslocation-filerepository-q","errorCode":null,"errorMessage":"unable to parse assetsLocation.fileRepository %q: %v","messagePattern":"unable to parse assetsLocation\\.fileRepository %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/assets/builder.go","lineNumber":458,"sourceCode":"\n\tif a.assetsLocation != nil && a.assetsLocation.FileRepository != nil {\n\t\treturn nil, fmt.Errorf(\"you might have not staged your files correctly, please execute 'kops get assets --copy'\")\n\t}\n\treturn nil, fmt.Errorf(\"cannot determine hash for %q (have you specified a valid file location?)\", u)\n}\n\nfunc (a *AssetBuilder) remapURL(canonicalURL *url.URL) (*url.URL, error) {\n\tf := \"\"\n\tif a.assetsLocation != nil {\n\t\tf = values.StringValue(a.assetsLocation.FileRepository)\n\t}\n\tif f == \"\" {\n\t\treturn nil, fmt.Errorf(\"assetsLocation.fileRepository must be set to remap asset %v\", canonicalURL)\n\t}\n\n\tfileRepo, err := url.Parse(f)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse assetsLocation.fileRepository %q: %v\", f, err)\n\t}\n\n\tfileRepo.Path = path.Join(fileRepo.Path, canonicalURL.Path)\n\t// Escape commas, which are legal in a path but separate locations in CompactString.\n\tfileRepo.RawPath = strings.ReplaceAll(fileRepo.EscapedPath(), \",\", \"%2C\")\n\n\treturn fileRepo, nil\n}\n\nfunc NormalizeImage(a *AssetBuilder, image string) string {\n\tif a.assetsLocation != nil && a.assetsLocation.ContainerProxy != nil {\n\t\tcontainerProxy := strings.TrimSuffix(*a.assetsLocation.ContainerProxy, \"/\")\n\t\tnormalized := image\n\n\t\t// If the image name contains only a single / we need to determine if the image is located on docker-hub or if it's using a convenient URL,\n\t\t// like registry.k8s.io/<image-name> or registry.k8s.io/<image-name>\n\t\t// In case of a hub image it should be sufficient to just prepend the proxy url, producing eg docker-proxy.example.com/weaveworks/weave-kube\n\t\tif strings.Count(normalized, \"/\") <= 1 && !strings.ContainsAny(strings.Split(normalized, \"/\")[0], \".:\") {","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/assets/builder.go#L440-L476","documentation":"After confirming assetsLocation.fileRepository is non-empty, remapURL parses it with url.Parse to build the mirror base URL. If the configured string is not a valid URL, parsing fails and the builder wraps the url.Parse error with this message. It prevents malformed repository URLs from producing corrupt asset paths.","triggerScenarios":"Setting cluster.spec.assetsLocation.fileRepository to a string that url.Parse rejects, e.g. one containing invalid characters, control characters, or a bad scheme like \"ht tp://repo\" or \"::not a url::\".","commonSituations":"Typo or stray whitespace/quotes when copying the repository URL into the cluster spec; unescaped special characters (spaces, braces) in a YAML value; generating the spec programmatically with an unvalidated string.","solutions":["Fix cluster.spec.assetsLocation.fileRepository to a well-formed absolute URL (scheme + host), e.g. https://artifacts.example.com/kops, then kops update cluster.","Validate the URL locally before applying: `go run` or `python3 -c \"import urllib.parse;urllib.parse.urlparse('YOUR_VALUE')\"`.","Quote the YAML value and check for hidden whitespace/control characters: kops get cluster -o yaml | grep fileRepository."],"exampleFix":"// before\nfileRepository: \"ht tp://artifacts example.com/kops\"\n// after\nfileRepository: \"https://artifacts.example.com/kops\"","handlingStrategy":"validation","validationCode":"repo := cluster.Spec.AssetsLocation.FileRepository\nif _, err := url.Parse(repo); err != nil {\n    return fmt.Errorf(\"fileRepository %q is not a valid URL: %w\", repo, err)\n}","typeGuard":"func validURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"u, err := builder.RemapFile(canonicalURL)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"unable to parse assetsLocation.fileRepository\") {\n        return fmt.Errorf(\"check spec.assetsLocation.fileRepository in the cluster spec: %w\", err)\n    }\n    return err\n}","preventionTips":["Store fileRepository as a quoted YAML string to avoid YAML mangling special characters.","Validate URLs with url.Parse (require scheme+host) in any tooling that generates the cluster spec.","Reject values containing spaces or control characters at spec-edit time."],"tags":["go","url-parse","configuration","kops"],"backgroundTag":"invalid-url","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}