{"record":{"id":"09329302662f97dd","repo":"hashicorp/terraform","slug":"invalid-source-address-s","errorCode":null,"errorMessage":"invalid source address: %s","messagePattern":"invalid source address: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/detect_remote_shorthands.go","lineNumber":93,"sourceCode":"\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}\n\n\t\treturn result, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"invalid source address: %s\", src)\n}\n\nfunc getForcedSourceType(src string) (string, string) {\n\tvar forced string\n\tif ms := forcedRegexp.FindStringSubmatch(src); ms != nil {\n\t\tforced = ms[1]\n\t\tsrc = ms[2]\n\t}\n\n\treturn forced, src\n}\n","sourceCodeStart":75,"sourceCodeEnd":105,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/detect_remote_shorthands.go#L75-L105","documentation":"The terminal fallback in detectRemoteSourceShorthands (internal/getmodules/moduleaddrs/detect_remote_shorthands.go:93). It fires when the source is not already a valid URL with a scheme AND none of the registered detectors (detectGitHub, detectGit, detectBitBucket, detectGCS, detectS3, detectAbsFilePath) recognize it. In other words, the string matches no known local-path, registry, URL, or shorthand form, so Terraform gives up.","triggerScenarios":"A module source that is a bare word (e.g. 'consul'), a typo'd registry address ('hashicorp/consul'), a URL missing its scheme ('github.com/user/repo' without the github detector matching due to malformed structure), or any string that fails every detector.","commonSituations":"Forgetting the registry address format (namespace/name/system vs. just name); omitting the URL scheme; typos in hostnames; referencing a module by a friendly name that is neither a registry entry nor a path.","solutions":["For a registry module, use the full three- or four-part address: namespace/name/system (e.g. hashicorp/consul/aws).","For a remote URL, include the scheme: https://..., git::ssh://..., s3::https://....","For a local module, prefix the path with ./ or ../ (e.g. ./modules/network).","Double-check the spelling of every path segment; a single typo can cause every detector to miss."],"exampleFix":"// before\nmodule \"x\" { source = \"hashicorp-consul\" }\n// after\nmodule \"x\" { source = \"hashicorp/consul/aws\" }","handlingStrategy":"validation","validationCode":"// Reject sources that no detector or parser can handle before calling detect.\nfunc looksLikeValidSource(s string) bool {\n\tfor _, p := range []string{\"./\", \"../\", \".\\\\\", \"..\\\\\"} {\n\t\tif strings.HasPrefix(s, p) {\n\t\t\treturn true\n\t\t}\n\t}\n\tif u, err := url.Parse(s); err == nil && u.Scheme != \"\" {\n\t\treturn true\n\t}\n\tparts := strings.Split(s, \"/\")\n\t// registry: NAMESPACE/NAME/SYSTEM (3) or HOST/NAMESPACE/NAME/SYSTEM (4)\n\treturn len(parts) == 3 || len(parts) == 4\n}","typeGuard":null,"tryCatchPattern":"addr, err := moduleaddrs.ParseModuleSource(src)\nif err != nil {\n    return fmt.Errorf(\"%s is not a valid module source (use namespace/name/system, a URL, or a ./local path): %w\", src, err)\n}","preventionTips":["Always qualify registry modules as namespace/name/system.","Prefix local modules with ./ or ../.","Include the URL scheme for remote sources.","Lint module source strings in CI with a regex matching the accepted forms."],"tags":["module-source","validation","shorthand","parsing"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}