golang/go · error
invalid version control suffix in %s path
Error message
invalid version control suffix in %s path
What it means
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.
Source
Thrown at src/cmd/go/internal/vcs/vcs.go:1317
repo: "https://{root}",
},
// General syntax for any server.
// Must be last.
{
regexp: lazyregexp.New(`(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[\w.\-]+)+?)\.(?P<vcs>fossil|git|hg|svn))(/~?[\w.\-]+)*$`),
schemelessRepo: true,
},
}
// noVCSSuffix checks that the repository name does not
// end in .foo for any version control system foo.
// The usual culprit is ".git".
func noVCSSuffix(match map[string]string) error {
repo := match["repo"]
for _, vcs := range vcsList {
if strings.HasSuffix(repo, "."+vcs.Cmd) {
return fmt.Errorf("invalid version control suffix in %s path", match["prefix"])
}
}
return nil
}
// importError is a copy of load.importError, made to avoid a dependency cycle
// on cmd/go/internal/load. It just needs to satisfy load.ImportPathError.
type importError struct {
importPath string
err error
}
func importErrorf(path, format string, args ...any) error {
err := &importError{importPath: path, err: fmt.Errorf(format, args...)}
if errStr := err.Error(); !strings.Contains(errStr, path) {
panic(fmt.Sprintf("path %q not in error %q", path, errStr))
}
return errView on GitHub (pinned to b6b368adc5)
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
Example fix
// before import "example.com/repo.git/pkg" // after import "example.com/repo/pkg"
Defensive patterns
Strategy: type-guard
Type guard
// Reject import paths carrying a VCS suffix before resolving
func hasVCSSuffix(path string) bool {
for _, s := range []string{".git", ".hg", ".svn", ".fossil", ".bzr"} {
if strings.Contains(path, s+"/") || strings.HasSuffix(path, s) { return true }
}
return false
} Prevention
- Strip .git from import paths copied out of clone URLs
- Use the path from the module's go.mod as the source of truth
When it happens
Trigger: Importing a path that matches the general server regexp with a trailing .<vcs>, e.g. 'example.com/repo.git/pkg'.
Common situations: User copy-pastes a clone URL including the .git extension; legacy gopkg.in-style paths with suffixes.
Related errors
- ReadZip: encoded file exceeds allowed size
- disallowed import path %q
- unknown import path %q: internal error: module loader did no
- https fetch: %v
- parsing %s: %v
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/083ca354245198a4.
Report an issue: GitHub.