golang/go · error
can only use path@version syntax with 'go get' and 'go insta
Error message
can only use path@version syntax with 'go get' and 'go install' in module-aware mode
What it means
An import path or package argument containing an @ symbol (version qualifier, e.g., foo@v1.2.3) was used in a context that doesn't support it. The @version syntax is only valid with go get and go install in module-aware mode. Using it in other commands (go build, go run, go test) or in GOPATH mode triggers this error. The check fires during package loading when strings.Contains(path, '@') is true.
Source
Thrown at src/cmd/go/internal/load/pkg.go:863
func loadPackageData(ld *modload.Loader, ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
ctx, span := trace.StartSpan(ctx, "load.loadPackageData "+path)
defer span.Done()
if path == "" {
panic("loadPackageData called with empty package path")
}
if strings.HasPrefix(path, "mod/") {
// Paths beginning with "mod/" might accidentally
// look in the module cache directory tree in $GOPATH/pkg/mod/.
// This prefix is owned by the Go core for possible use in the
// standard library (since it does not begin with a domain name),
// so it's OK to disallow entirely.
return nil, false, fmt.Errorf("disallowed import path %q", path)
}
if strings.Contains(path, "@") {
return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
}
// Determine canonical package path and directory.
// For a local import the identifier is the pseudo-import path
// we create from the full directory to the package.
// Otherwise it is the usual import path.
// For vendored imports, it is the expanded form.
//
// Note that when modules are enabled, local import paths are normally
// canonicalized by modload.LoadPackages before now. However, if there's an
// error resolving a local path, it will be returned untransformed
// so that 'go list -e' reports something useful.
importKey := importSpec{
path: path,
parentPath: parentPath,
parentDir: parentDir,
parentRoot: parentRoot,
parentIsStd: parentIsStd,View on GitHub (pinned to b6b368adc5)
Solutions
- Use go get or go install for version-qualified packages: 'go install foo@v1.2.3' instead of 'go build foo@v1.2.3'
- If you need a specific version for building, run 'go get foo@v1.2.3' first to update go.mod, then 'go build ./...'
- Ensure GO111MODULE is not set to off — use 'on' or 'auto' (the default in modern Go)
- Remove any @version syntax from import paths in source code — version pinning belongs in go.mod, not in import statements
Example fix
// before: using @version with wrong command // $ go build golang.org/x/tools/cmd/goimports@latest // # error: can only use path@version syntax with go get and go install // after: use go install for version-qualified packages // $ go install golang.org/x/tools/cmd/goimports@latest // or for building local code with a specific dependency version: // $ go get golang.org/x/text@v0.14.0 // $ go build ./...
Defensive patterns
Strategy: validation
Validate before calling
// Validate that import paths and package arguments don't use @version
// in contexts that don't support it.
func validatePackageArg(path string, command string, moduleMode bool) error {
if strings.Contains(path, "@") {
if !moduleMode {
return fmt.Errorf("path@version requires module mode (GO111MODULE=on)")
}
if command != "get" && command != "install" {
return fmt.Errorf("path@version only supported with go get and go install")
}
}
return nil
}
// Check if module mode is active:
func isModuleMode() bool {
mode := os.Getenv("GO111MODULE")
return mode != "off" // "on", "auto", or empty all enable modules in modern Go
} Type guard
// This is a package loading error, returned as a plain error.
// Detect by message:
func isAtVersionError(err error) bool {
return err != nil && strings.Contains(err.Error(), "path@version syntax")
} Try / catch
// For tooling that loads packages:
// pkgs, err := packages.Load(cfg, pattern)
// if err != nil {
// if isAtVersionError(err) {
// // User passed foo@version with an unsupported command.
// // Strip the version or suggest go get/go install.
// base := path[:strings.Index(path, "@")]
// fmt.Printf("Use 'go get %s' to fetch the version, then rebuild\n", pattern)
// fmt.Printf("Or use 'go install %s'\n", pattern)
// }
// } Prevention
- Use go get or go install for version-qualified packages, not go build or go run
- Ensure GO111MODULE is set to 'on' or 'auto' (default) for module support
- Never put @version in source code import statements — version pinning goes in go.mod
- For building tools at a specific version, use: go install golang.org/x/tools/cmd/foo@v1.0.0
- For building local code with a specific dependency, run go get dep@version first, then go build ./...
- Check GO111MODULE with 'go env GO111MODULE' if module mode seems inactive
When it happens
Trigger: Package loading in load/pkg.go encounters strings.Contains(path, '@') == true during import path resolution. This happens when a package argument or import path contains @ but the current command is not go get/go install, or when GO111MODULE=off (GOPATH mode) is active.
Common situations: Running go build or go run with a package@version argument (e.g., 'go build foo@v1.2.3'); using @version syntax in an import statement in source code; running in GOPATH mode (GO111MODULE=off) where version qualifiers aren't supported; using @version with go list or other commands that don't support it; misunderstanding module-mode semantics.
Related errors
- syntax error
- use of vendored package not allowed
- binary-only packages are no longer supported
- not a directory
- not completely extracted
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b8f96576c0e82c42.
Report an issue: GitHub.