{"record":{"id":"efe90850bbc07b6b","repo":"golang/go","slug":"s-argument-must-be-a-clean-package-path","errorCode":null,"errorMessage":"%s: argument must be a clean package path","messagePattern":"(.+?): argument must be a clean package path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/load/pkg.go","lineNumber":3411,"sourceCode":"\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\tpatterns := make([]string, len(args))\n\tfor i, arg := range args {\n\t\tp, found := strings.CutSuffix(arg, \"@\"+version)\n\t\tif !found {\n\t\t\treturn nil, fmt.Errorf(\"%s: all arguments must refer to packages in the same module at the same version (@%s)\", arg, version)\n\t\t}\n\t\tswitch {\n\t\tcase build.IsLocalImport(p):\n\t\t\treturn nil, fmt.Errorf(\"%s: argument must be a package path, not a relative path\", arg)\n\t\tcase filepath.IsAbs(p):\n\t\t\treturn nil, fmt.Errorf(\"%s: argument must be a package path, not an absolute path\", arg)\n\t\tcase search.IsMetaPackage(p):\n\t\t\treturn nil, fmt.Errorf(\"%s: argument must be a package path, not a meta-package\", arg)\n\t\tcase pathpkg.Clean(p) != p:\n\t\t\treturn nil, fmt.Errorf(\"%s: argument must be a clean package path\", arg)\n\t\tcase !strings.Contains(p, \"...\") && search.IsStandardImportPath(p) && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):\n\t\t\treturn nil, fmt.Errorf(\"%s: argument must not be a package in the standard library\", arg)\n\t\tdefault:\n\t\t\tpatterns[i] = p\n\t\t}\n\t}\n\tpatterns = search.CleanPatterns(patterns)\n\n\t// Query the module providing the first argument, load its go.mod file, and\n\t// check that it doesn't contain directives that would cause it to be\n\t// interpreted differently if it were the main module.\n\t//\n\t// If multiple modules match the first argument, accept the longest match\n\t// (first result). It's possible this module won't provide packages named by\n\t// later arguments, and other modules would. Let's not try to be too\n\t// magical though.\n\tallowed := ld.CheckAllowed\n\tif modload.IsRevisionQuery(firstPath, version) {","sourceCodeStart":3393,"sourceCodeEnd":3429,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/load/pkg.go#L3393-L3429","documentation":"Thrown by the Go command's package@version install workflow (e.g. `go install pkg@v1.0.0`). After stripping the `@version` suffix, the remaining path `p` is rejected when `pathpkg.Clean(p) != p`, i.e. the path is not in canonical form. The command requires a clean import path because non-canonical forms (redundant slashes, stray `.`/`..` segments) make module resolution ambiguous.","triggerScenarios":"Running `go install` or `go get pkg@version` where the path portion contains double slashes, leading/trailing slashes, or `.`/`..` segments, e.g. `go install example.com/foo//bar@v1.0.0` or `go install example.com/./pkg@latest`.","commonSituations":"Copy-pasting a path with stray slashes; building the argument string programmatically without cleaning it; concatenating path fragments that introduce redundant separators.","solutions":["Remove redundant `/`, leading/trailing separators, and `.`/`..` segments from the path portion before `@version`.","If constructing the argument in code, run `path.Clean(p)` and assert it equals `p` before appending `@version`.","Use the canonical module root path exactly as it appears in the module's go.mod `module` directive."],"exampleFix":"// before\ngo install example.com/foo/../bar@v1.0.0\n\n// after\ngo install example.com/bar@v1.0.0","handlingStrategy":"validation","validationCode":"import \"path\"\n\nfunc cleanPackageArg(p, version string) (string, error) {\n    if path.Clean(p) != p {\n        return \"\", fmt.Errorf(\"path %q is not clean; use %q\", p, path.Clean(p))\n    }\n    return p + \"@\" + version, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never build package@version strings by raw concatenation; clean the path first with path.Clean.","Pull module paths directly from the module's published go.mod rather than typing them.","Add a lint step in build scripts that rejects non-canonical import paths."],"tags":["go-toolchain","module","package-path","install"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}