{"record":{"id":"083ca354245198a4","repo":"golang/go","slug":"invalid-version-control-suffix-in-s-path","errorCode":null,"errorMessage":"invalid version control suffix in %s path","messagePattern":"invalid version control suffix in (.+?) path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/vcs/vcs.go","lineNumber":1317,"sourceCode":"\t\trepo:       \"https://{root}\",\n\t},\n\n\t// General syntax for any server.\n\t// Must be last.\n\t{\n\t\tregexp:         lazyregexp.New(`(?P<root>(?P<repo>([a-z0-9.\\-]+\\.)+[a-z0-9.\\-]+(:[0-9]+)?(/~?[\\w.\\-]+)+?)\\.(?P<vcs>fossil|git|hg|svn))(/~?[\\w.\\-]+)*$`),\n\t\tschemelessRepo: true,\n\t},\n}\n\n// noVCSSuffix checks that the repository name does not\n// end in .foo for any version control system foo.\n// The usual culprit is \".git\".\nfunc noVCSSuffix(match map[string]string) error {\n\trepo := match[\"repo\"]\n\tfor _, vcs := range vcsList {\n\t\tif strings.HasSuffix(repo, \".\"+vcs.Cmd) {\n\t\t\treturn fmt.Errorf(\"invalid version control suffix in %s path\", match[\"prefix\"])\n\t\t}\n\t}\n\treturn nil\n}\n\n// importError is a copy of load.importError, made to avoid a dependency cycle\n// on cmd/go/internal/load. It just needs to satisfy load.ImportPathError.\ntype importError struct {\n\timportPath string\n\terr        error\n}\n\nfunc importErrorf(path, format string, args ...any) error {\n\terr := &importError{importPath: path, err: fmt.Errorf(format, args...)}\n\tif errStr := err.Error(); !strings.Contains(errStr, path) {\n\t\tpanic(fmt.Sprintf(\"path %q not in error %q\", path, errStr))\n\t}\n\treturn err","sourceCodeStart":1299,"sourceCodeEnd":1335,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/vcs/vcs.go#L1299-L1335","documentation":"noVCSSuffix rejects an import path whose repository component ends in a VCS command suffix (e.g. '.git', '.hg'). The %s is the matched prefix. This prevents ambiguous paths like 'host/foo.git/sub' that would otherwise be parsed as a VCS-suffixed repo.","triggerScenarios":"Importing a path that matches the general server regexp with a trailing .<vcs>, e.g. 'example.com/repo.git/pkg'.","commonSituations":"User copy-pastes a clone URL including the .git extension; legacy gopkg.in-style paths with suffixes.","solutions":["Drop the VCS suffix from the import path (use 'example.com/repo' not 'example.com/repo.git')","For GitHub, use the plain module path without .git"],"exampleFix":"// before\nimport \"example.com/repo.git/pkg\"\n// after\nimport \"example.com/repo/pkg\"","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Reject import paths carrying a VCS suffix before resolving\nfunc hasVCSSuffix(path string) bool {\n  for _, s := range []string{\".git\", \".hg\", \".svn\", \".fossil\", \".bzr\"} {\n    if strings.Contains(path, s+\"/\") || strings.HasSuffix(path, s) { return true }\n  }\n  return false\n}","tryCatchPattern":null,"preventionTips":["Strip .git from import paths copied out of clone URLs","Use the path from the module's go.mod as the source of truth"],"tags":["go","modules","vcs","import-path"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}