{"record":{"id":"077310f8524796cb","repo":"hashicorp/terraform","slug":"error-parsing-url-s","errorCode":null,"errorMessage":"Error parsing URL: %s","messagePattern":"Error parsing URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/detect_remote_shorthands.go","lineNumber":70,"sourceCode":"\n\t\tvar detectForce string\n\t\tdetectForce, result = getForcedSourceType(result)\n\t\tresult, detectSubdir := SplitPackageSubdir(result)\n\n\t\t// If we have a subdir from the detection, then prepend it to our\n\t\t// requested subdir.\n\t\tif detectSubdir != \"\" {\n\t\t\tif subDir != \"\" {\n\t\t\t\tsubDir = filepath.Join(detectSubdir, subDir)\n\t\t\t} else {\n\t\t\t\tsubDir = detectSubdir\n\t\t\t}\n\t\t}\n\n\t\tif subDir != \"\" {\n\t\t\tu, err := url.Parse(result)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"Error parsing URL: %s\", err)\n\t\t\t}\n\t\t\tu.Path += \"//\" + subDir\n\n\t\t\t// a subdir may contain wildcards, but in order to support them we\n\t\t\t// have to ensure the path isn't escaped.\n\t\t\tu.RawPath = u.Path\n\n\t\t\tresult = u.String()\n\t\t}\n\n\t\t// Preserve the forced getter if it exists. We try to use the\n\t\t// original set force first, followed by any force set by the\n\t\t// detector.\n\t\tif getForce != \"\" {\n\t\t\tresult = fmt.Sprintf(\"%s::%s\", getForce, result)\n\t\t} else if detectForce != \"\" {\n\t\t\tresult = fmt.Sprintf(\"%s::%s\", detectForce, result)\n\t\t}","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/detect_remote_shorthands.go#L52-L88","documentation":"Raised in detectRemoteSourceShorthands (internal/getmodules/moduleaddrs/detect_remote_shorthands.go:70). When a shorthand detector (GitHub, BitBucket, S3, GCS, etc.) succeeds and a subdirectory was detected or supplied, the result is re-parsed with url.Parse so the subdir can be appended to the path. If that reconstructed string fails to parse, this error is returned. Because detectors build the URL from controlled components, this path is rarely hit and usually signals an unusual character in the source.","triggerScenarios":"A shorthand source (e.g. github.com/user/repo//subdir) where the detector-produced base URL plus an embedded subdir combine into a string url.Parse rejects, such as an unescaped space or control character in the repo/subdir portion that survived the detector but breaks re-parse.","commonSituations":"A module source with a subdir containing spaces or non-ASCII characters without escaping; copy-paste artifacts in the source string; rare detector edge cases.","solutions":["Replace the shorthand with a fully-qualified URL that includes the scheme (https://...) so the detector/re-parse step is bypassed.","Remove or escape special characters (spaces, control chars) in the subdir portion of the address.","If the source looks valid, simplify by dropping the '//subdir' part and test the base package address in isolation to isolate the bad segment."],"exampleFix":"// before\nmodule \"x\" { source = \"github.com/user/repo//sub dir\" }\n// after\nmodule \"x\" { source = \"github.com/user/repo//sub-dir\" }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"result, err := moduleaddrs.DetectRemoteSourceShorthands(src)\nif err != nil {\n    // Re-parse failed after a detector ran; fall back to a canonical URL.\n    if u, e := url.Parse(src); e == nil && u.Scheme != \"\" {\n        result = src\n    } else {\n        return err\n    }\n}","preventionTips":["Use fully-qualified URLs with an explicit scheme to bypass shorthand detection entirely.","Avoid special characters (spaces, control chars) in repo names and subdir segments.","Keep subdir segments simple and URL-safe."],"tags":["url-parsing","module-source","shorthand","subdir"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}