{"record":{"id":"56d1c6133bb3f3fa","repo":"golang/go","slug":"build-output-q-already-exists-and-is-not-an-objec","errorCode":null,"errorMessage":"build output %q already exists and is not an object file","messagePattern":"build output %q already exists and is not an object file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/shell.go","lineNumber":256,"sourceCode":"// When running as a user with sufficient privileges, we may delete\n// even device files, for example, which is not intended.\nfunc mayberemovefile(s string) {\n\tif fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {\n\t\treturn\n\t}\n\tos.Remove(s)\n}\n\n// Be careful about removing/overwriting dst.\n// Do not remove/overwrite if dst exists and is a directory\n// or a non-empty non-object file.\nfunc checkDstOverwrite(dst string, force bool) error {\n\tif fi, err := os.Stat(dst); err == nil {\n\t\tif fi.IsDir() {\n\t\t\treturn fmt.Errorf(\"build output %q already exists and is a directory\", dst)\n\t\t}\n\t\tif !force && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(dst) {\n\t\t\treturn fmt.Errorf(\"build output %q already exists and is not an object file\", dst)\n\t\t}\n\t}\n\treturn nil\n}\n\n// writeFile writes the text to file.\nfunc (sh *Shell) writeFile(file string, text []byte) error {\n\tif cfg.BuildN || cfg.BuildX {\n\t\tswitch {\n\t\tcase len(text) == 0:\n\t\t\tsh.ShowCmd(\"\", \"echo -n > %s # internal\", file)\n\t\tcase bytes.IndexByte(text, '\\n') == len(text)-1:\n\t\t\t// One line. Use a simpler \"echo\" command.\n\t\t\tsh.ShowCmd(\"\", \"echo '%s' > %s # internal\", bytes.TrimSuffix(text, []byte(\"\\n\")), file)\n\t\tdefault:\n\t\t\t// Use the most general form.\n\t\t\tsh.ShowCmd(\"\", \"cat >%s << 'EOF' # internal\\n%sEOF\", file, text)\n\t\t}","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/shell.go#L238-L274","documentation":"Thrown by checkDstOverwrite when the build output path exists, is a non-empty regular file, is not recognized as an object file (isObject returns false), and the build is not forced. This protects user files from being clobbered by an accidental `go build -o`.","triggerScenarios":"Run `go build -o notes.txt` (or any existing non-object file) without force; os.Stat finds a regular file with Size()!=0, isObject(dst) is false, force is false, so the error fires.","commonSituations":"Reusing a filename that holds a README/script/data file; CI sharing an output name with an artifact from another tool; pointing `-o` at an existing shell script.","solutions":["Choose a fresh output filename that does not collide with existing data.","Rename or back up the existing file before building.","Confirm the existing file is safe to overwrite, then force: `go build -o notes.txt` is not forceable in user space — instead delete it first (`rm notes.txt`) or use a different name.","Verify isObject expectations: the check only auto-overwrites recognized object/binary files."],"exampleFix":"# before\n// go build -o run.sh   (run.sh exists, non-empty, not an object)\n\n# after\n// mv run.sh run.sh.bak && go build -o run.sh","handlingStrategy":"validation","validationCode":"// Refuse to clobber non-object files\nout := flag.Arg(0)\nif fi, err := os.Stat(out); err == nil && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(out) {\n    log.Fatalf(\"%s exists and is not an object file; rename or remove first\", out)\n}","typeGuard":"func isObject(p string) bool {\n    f, err := os.Open(p)\n    if err != nil { return false }\n    defer f.Close()\n    var magic [4]byte\n    n, _ := f.Read(magic[:])\n    if n < 4 { return false }\n    // ELF \\x7fELF, Mach-O \\xfe\\xed\\xfa\\xce/\\xcf, PE \"MZ\"\n    return bytes.Equal(magic[:4], []byte{0x7f, 'E', 'L', 'F'}) ||\n        magic[0] == 'M' && magic[1] == 'Z'\n}","tryCatchPattern":null,"preventionTips":["Do not point -o at existing scripts/notes/data.","Use a dedicated ./bin path for build outputs.","Back up files before reusing a name for -o."],"tags":["go-toolchain","build","filesystem","validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}