{"record":{"id":"09f0ddde8a7bec94","repo":"hashicorp/terraform","slug":"error-parsing-gcs-url-s","errorCode":null,"errorMessage":"error parsing GCS URL: %s","messagePattern":"error parsing GCS URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/detect_gcs.go","lineNumber":32,"sourceCode":"func detectGCS(src string) (string, bool, error) {\n\tif len(src) == 0 {\n\t\treturn \"\", false, nil\n\t}\n\n\tif strings.Contains(src, \"googleapis.com/\") {\n\t\tparts := strings.Split(src, \"/\")\n\t\tif len(parts) < 5 {\n\t\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\t\"URL is not a valid GCS URL\")\n\t\t}\n\t\tversion := parts[2]\n\t\tbucket := parts[3]\n\t\tobject := strings.Join(parts[4:], \"/\")\n\n\t\turl, err := url.Parse(fmt.Sprintf(\"https://www.googleapis.com/storage/%s/%s/%s\",\n\t\t\tversion, bucket, object))\n\t\tif err != nil {\n\t\t\treturn \"\", false, fmt.Errorf(\"error parsing GCS URL: %s\", err)\n\t\t}\n\n\t\treturn \"gcs::\" + url.String(), true, nil\n\t}\n\n\treturn \"\", false, nil\n}\n","sourceCodeStart":14,"sourceCodeEnd":40,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/detect_gcs.go#L14-L40","documentation":"Returned by detectGCS (detect_gcs.go:32) when url.Parse fails on the https URL constructed from the split GCS path segments. After assembling https://www.googleapis.com/storage/<version>/<bucket>/<object>, net/url.Parse rejects it. In practice this is rare because the constructed URL is largely controlled, but malformed user-supplied segments (e.g. invalid characters) can break parsing.","triggerScenarios":"A GCS source string whose version/bucket/object segments contain characters that make the assembled URL invalid per net/url.Parse rules (e.g. spaces, control characters, or malformed percent-encoding).","commonSituations":"A bucket or object name with spaces or special characters not URL-encoded. A trailing fragment or query that confuses the parser. Cut-paste of a URL with stray characters. Non-ASCII object names.","solutions":["URL-encode any special characters in the bucket/object path segments of the source string.","Simplify the source to ASCII-safe segment names and re-test.","Prefer the explicit gcs::https://... form with a fully-formed, valid URL instead of relying on shorthand detection.","Check the parse error detail in the message for the specific offending token."],"exampleFix":"# before — object name has a space\nsource = \"googleapis.com/storage/v1/my-bucket/my module.zip\"\n\n# after — encode special characters\nsource = \"googleapis.com/storage/v1/my-bucket/my%20module.zip\"","handlingStrategy":"validation","validationCode":"// Pre-parse the assembled GCS URL to catch malformed segments\nfunc gcsURLParses(src string) bool {\n    if !strings.Contains(src, \"googleapis.com/\") {\n        return true\n    }\n    parts := strings.Split(src, \"/\")\n    if len(parts) < 5 {\n        return false\n    }\n    u := fmt.Sprintf(\"https://www.googleapis.com/storage/%s/%s/%s\",\n        parts[2], parts[3], strings.Join(parts[4:], \"/\"))\n    _, err := url.Parse(u)\n    return err == nil\n}","typeGuard":"func gcsURLParses(src string) bool {\n    parts := strings.Split(src, \"/\")\n    if len(parts) < 5 {\n        return false\n    }\n    u := fmt.Sprintf(\"https://www.googleapis.com/storage/%s/%s/%s\",\n        parts[2], parts[3], strings.Join(parts[4:], \"/\"))\n    _, err := url.Parse(u)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["URL-encode special characters in GCS bucket/object names.","Avoid spaces and control characters in module source strings.","Use the explicit gcs:: URL form for non-trivial object paths."],"tags":["getmodules","gcs","module-source","url-parsing","modules"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}