{"record":{"id":"3ecf51d6dead8a02","repo":"hashicorp/terraform","slug":"error-parsing-git-ssh-url-s","errorCode":null,"errorMessage":"error parsing Git SSH URL: %s","messagePattern":"error parsing Git SSH URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/detect_git.go","lineNumber":131,"sourceCode":"\t}\n\n\tuser := matched[1]\n\thost := matched[2]\n\tpath := matched[3]\n\tqidx := strings.Index(path, \"?\")\n\tif qidx == -1 {\n\t\tqidx = len(path)\n\t}\n\n\tvar u url.URL\n\tu.Scheme = \"ssh\"\n\tu.User = url.User(user)\n\tu.Host = host\n\tu.Path = path[0:qidx]\n\tif qidx < len(path) {\n\t\tq, err := url.ParseQuery(path[qidx+1:])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing Git SSH URL: %s\", err)\n\t\t}\n\t\tu.RawQuery = q.Encode()\n\t}\n\n\treturn &u, nil\n}\n","sourceCodeStart":113,"sourceCodeEnd":138,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/detect_git.go#L113-L138","documentation":"Raised in detectSSH (internal/getmodules/moduleaddrs/detect_git.go:131) when normalizing an SCP-like SSH module source (e.g. git@github.com:org/repo.git?depth=1). After the colon-delimited path is split on '?', the query portion is parsed with url.ParseQuery; if that fails (typically invalid percent-encoding such as %zz), this error propagates up through detectGit. The first return value of detectGit is also flagged true so callers treat it as a hard error rather than 'not recognized'.","triggerScenarios":"A module source string matching the SSH pattern (user@host:path) whose query string after '?' contains an invalid percent-escape or malformed key=value pair, e.g. git@example.com:org/repo.git?ref=%zz or git@host:repo?foo===bar. url.ParseQuery rejects bad escapes and bad syntax.","commonSituations":"A developer copies a git clone URL with query args (depth, ref, sshkey) and accidentally includes a literal '%' that is not a valid hex escape; CI templating that injects unescaped tokens into the query string; Windows users pasting URLs with stray characters.","solutions":["Inspect the '?' portion of the SSH source string and fix or remove any invalid percent-encoded sequences (e.g. replace %zz with %25zz or drop the bad param).","Percent-encode any literal '%' in query parameters as %25 before embedding them in the module source.","Switch from SCP shorthand to a full ssh:// URL (ssh://git@example.com/org/repo.git?depth=1), which is parsed more leniently and avoids the SCP-path query extraction.","Drop unnecessary query parameters and rely on go-getter defaults."],"exampleFix":"// before\nmodule \"x\" { source = \"git@github.com:org/repo.git?depth=%zz\" }\n// after\nmodule \"x\" { source = \"git@github.com:org/repo.git?depth=1\" }","handlingStrategy":"validation","validationCode":"// Validate the query string of an SCP-style SSH source before detection.\nfunc validSSHQuery(src string) error {\n\tq := src\n\tif i := strings.Index(src, \"?\"); i != -1 {\n\t\tq = src[i+1:]\n\t\tif i2 := strings.Index(q, \"#\"); i2 != -1 {\n\t\t\tq = q[:i2]\n\t\t}\n\t}\n\tif q == \"\" {\n\t\treturn nil\n\t}\n\tif _, err := url.ParseQuery(q); err != nil {\n\t\treturn fmt.Errorf(\"invalid SSH query string %q: %w\", q, err)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"// detectGit-style errors surface as a normal Go error; branch on it.\nresult, ok, err := detectGit(src)\nif err != nil {\n    // src matched the SSH pattern but its query was malformed;\n    // fix/encode the source and retry, do not silently ignore.\n    return fmt.Errorf(\"module source %q is not a valid SSH URL: %w\", src, err)\n}","preventionTips":["Prefer full ssh:// URLs over SCP shorthand when query parameters are needed.","Always percent-encode literal '%' as %25 inside query strings.","In CI, render module sources from a template after URL-encoding parameter values."],"tags":["git","ssh","url-parsing","module-source"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}