{"record":{"id":"f8a959a0a33d3a95","repo":"golang/go","slug":"gopath-entry-cannot-start-with-shell-metacharacter","errorCode":null,"errorMessage":"GOPATH entry cannot start with shell metacharacter '~': %q","messagePattern":"GOPATH entry cannot start with shell metacharacter '~': %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/envcmd/env.go","lineNumber":668,"sourceCode":"\t// To catch typos and the like, check that we know the variable.\n\t// If it's already in the env file, we assume it's known.\n\tif !cfg.CanGetenv(key) {\n\t\treturn fmt.Errorf(\"unknown go command variable %s\", key)\n\t}\n\n\t// Some variables can only have one of a few valid values. If set to an\n\t// invalid value, the next cmd/go invocation might fail immediately,\n\t// even 'go env -w' itself.\n\tswitch key {\n\tcase \"GO111MODULE\":\n\t\tswitch val {\n\t\tcase \"\", \"auto\", \"on\", \"off\":\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid %s value %q\", key, val)\n\t\t}\n\tcase \"GOPATH\":\n\t\tif strings.HasPrefix(val, \"~\") {\n\t\t\treturn fmt.Errorf(\"GOPATH entry cannot start with shell metacharacter '~': %q\", val)\n\t\t}\n\t\tif !filepath.IsAbs(val) && val != \"\" {\n\t\t\treturn fmt.Errorf(\"GOPATH entry is relative; must be absolute path: %q\", val)\n\t\t}\n\tcase \"GOMODCACHE\":\n\t\tif !filepath.IsAbs(val) && val != \"\" {\n\t\t\treturn fmt.Errorf(\"GOMODCACHE entry is relative; must be absolute path: %q\", val)\n\t\t}\n\tcase \"CC\", \"CXX\":\n\t\tif val == \"\" {\n\t\t\tbreak\n\t\t}\n\t\targs, err := quoted.Split(val)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid %s: %v\", key, err)\n\t\t}\n\t\tif len(args) == 0 {\n\t\t\treturn fmt.Errorf(\"%s entry cannot contain only space\", key)","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/envcmd/env.go#L650-L686","documentation":"Returned by checkEnvWrite when a GOPATH entry starts with '~'. The tilde is a shell metacharacter that the go command does not expand, so storing it would silently create a literal '~' directory. Rejected to prevent confusing path-resolution bugs later.","triggerScenarios":"`go env -w GOPATH=~/go`, or any GOPATH entry whose first character is '~' (including in colon-separated multi-entry GOPATH on POSIX).","commonSituations":"Users coming from bash configs that lean on tilde expansion; copy-pasting `export GOPATH=~/go` style lines into `go env -w`; cross-platform shell setups that assume tilde expansion.","solutions":["Expand the tilde yourself to an absolute path: `go env -w GOPATH=$HOME/go` after substituting $HOME, or use the resolved absolute path directly.","On multi-entry GOPATH, ensure none of the colon-separated entries begins with '~'.","Keep GOPATH configuration in your shell rc file (where tilde expansion happens) rather than in `go env -w`."],"exampleFix":"# before\n$ go env -w GOPATH=~/go\nerror: GOPATH entry cannot start with shell metacharacter '~'\n# after — expand the absolute path first\n$ go env -w GOPATH=\"$HOME/go\"","handlingStrategy":"validation","validationCode":"import \"strings\"\n\nfunc sanitizeGopathEntry(v string) (string, error) {\n    if strings.HasPrefix(v, \"~\") {\n        return \"\", fmt.Errorf(\"GOPATH must not start with '~': %q\", v)\n    }\n    return v, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always expand '~' to $HOME before persisting paths.","Keep tilde-dependent lines in shell rc files where the shell expands them.","Lint for tilde-prefixed paths in config generators."],"tags":["config","env","gopath","validation","shell"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}