{"record":{"id":"54f4d6b46bdeb386","repo":"golang/go","slug":"s-cannot-be-modified","errorCode":null,"errorMessage":"%s cannot be modified","messagePattern":"(.+?) cannot be modified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/envcmd/env.go","lineNumber":645,"sourceCode":"\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc checkEnvWrite(key, val string) error {\n\tswitch key {\n\tcase \"GOEXE\",\n\t\t\"GOGCCFLAGS\",\n\t\t\"GOHOSTARCH\",\n\t\t\"GOHOSTOS\",\n\t\t\"GOMOD\",\n\t\t\"GOROOT\",\n\t\t\"GOTELEMETRY\",\n\t\t\"GOTELEMETRYDIR\",\n\t\t\"GOTOOLDIR\",\n\t\t\"GOVERSION\",\n\t\t\"GOWORK\":\n\t\treturn fmt.Errorf(\"%s cannot be modified\", key)\n\tcase \"GOENV\", \"GODEBUG\":\n\t\treturn fmt.Errorf(\"%s can only be set using the OS environment\", key)\n\t}\n\n\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:","sourceCodeStart":627,"sourceCodeEnd":663,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/envcmd/env.go#L627-L663","documentation":"Returned by checkEnvWrite when `go env -w KEY=VAL` targets one of the read-only, computed variables: GOEXE, GOGCCFLAGS, GOHOSTARCH, GOHOSTOS, GOMOD, GOROOT, GOTELEMETRY, GOTELEMETRYDIR, GOTOOLDIR, GOVERSION, GOWORK. These reflect the active toolchain/session state, so the go command refuses to persist them into the go-env config file.","triggerScenarios":"Invoking `go env -w GOROOT=/custom/go`, `go env -w GOVERSION=...`, `go env -w GOMOD=...`, or any other listed key in checkEnvWrite's first switch case.","commonSituations":"Scripts trying to relocate GOROOT via `go env -w` instead of reinstalling or setting GOROOT in the OS environment; CI images attempting to pin GOVERSION; users confused between build-computed vars and user-settable ones.","solutions":["Set the variable in the OS environment (export GOROOT=...; or in the parent process env) rather than via `go env -w`.","For GOROOT specifically: install/use the desired Go toolchain (e.g. via go toolchain directives or GOTOOLCHAIN) instead of rewriting GOROOT.","Pick the correct user-settable equivalent — consult `go help environment` for the writable var list.","Remove the offending line from your setup script that calls `go env -w` on a computed key."],"exampleFix":"# before\n$ go env -w GOROOT=/opt/go-beta\nerror: GOROOT cannot be modified\n# after — set it in the shell/CI environment instead\n$ GOROOT=/opt/go-beta go build ./...","handlingStrategy":"validation","validationCode":"// Reject read-only keys before calling `go env -w`.\nvar readOnly = map[string]bool{\n    \"GOEXE\": true, \"GOGCCFLAGS\": true, \"GOHOSTARCH\": true,\n    \"GOHOSTOS\": true, \"GOMOD\": true, \"GOROOT\": true,\n    \"GOTELEMETRY\": true, \"GOTELEMETRYDIR\": true, \"GOTOOLDIR\": true,\n    \"GOVERSION\": true, \"GOWORK\": true,\n}\nfunc safeEnvW(key, val string) error {\n    if readOnly[key] {\n        return fmt.Errorf(\"%s cannot be set via `go env -w`; use OS env\", key)\n    }\n    return runGoEnvW(key, val)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Maintain a known-writable allowlist (from `go help environment`) in config tooling.","Prefer OS environment for toolchain-location vars; reserve `go env -w` for user preferences.","Document in CI scripts which vars are set via OS env vs go env file."],"tags":["config","env","go-command","validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}