{"record":{"id":"e3124ce54318a9e2","repo":"golang/go","slug":"copying-s-to-s-v-e3124c","errorCode":null,"errorMessage":"copying %s to %s: %v","messagePattern":"copying (.+?) to (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/shell.go","lineNumber":232,"sourceCode":"\tif err != nil && runtime.GOOS == \"windows\" {\n\t\t// Windows does not allow deletion of a binary file\n\t\t// while it is executing. Try to move it out of the way.\n\t\t// If the move fails, which is likely, we'll try again the\n\t\t// next time we do an install of this binary.\n\t\tif err := os.Rename(dst, dst+\"~\"); err == nil {\n\t\t\tos.Remove(dst + \"~\")\n\t\t}\n\t\tdf, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"copying %s: %w\", src, err) // err should already refer to dst\n\t}\n\n\t_, err = io.Copy(df, sf)\n\tdf.Close()\n\tif err != nil {\n\t\tmayberemovefile(dst)\n\t\treturn fmt.Errorf(\"copying %s to %s: %v\", src, dst, err)\n\t}\n\treturn nil\n}\n\n// mayberemovefile removes a file only if it is a regular file\n// 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 {","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/shell.go#L214-L250","documentation":"Thrown by copyFile when io.Copy fails partway through copying the build artifact to its destination (after the destination was successfully opened). The destination is removed via mayberemovefile to avoid leaving a corrupt partial binary, and the error names both source and destination.","triggerScenarios":"During `go install`/`go build -o`, io.Copy returns an error — e.g. disk fills mid-write, the source file vanishes, an I/O error occurs on the device, or (rarely) a signal interrupts the copy. The df/sf handles are opened fine, but the byte stream fails.","commonSituations":"Destination filesystem runs out of space mid-write; network filesystem (NFS/SMB) hiccup; hardware/disk error; build cache on a flaky volume; antivirus interfering on Windows.","solutions":["Check free space at the destination: `df -h <dst-dir>`; free space and rebuild.","If on a network fs, build to a local dir first (`go build -o /tmp/app`) and copy manually.","Inspect dmesg/system logs for I/O errors on the underlying device.","Retry the build; transient fs errors often clear."],"exampleFix":"# before\n// go build -o /mnt/nfs/app   (io.Copy fails)\n\n# after\n// go build -o ./app && cp ./app /mnt/nfs/app","handlingStrategy":"try-catch","validationCode":"// Check free space at destination before a large install\nvar st syscall.Statfs_t\nif err := syscall.Statfs(filepath.Dir(dst), &st); err == nil {\n    free := st.Bavail * uint64(st.Bsize)\n    if free < minFree { log.Fatalf(\"only %d bytes free at %s\", free, filepath.Dir(dst)) }\n}","typeGuard":null,"tryCatchPattern":"err := sh.copyFile(src, dst)\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && perr.Err == syscall.ENOSPC {\n        return fmt.Errorf(\"disk full while writing %s; free space and retry\", dst)\n    }\n    return err\n}","preventionTips":["Build to a local fast disk; copy artifacts over the network separately.","Monitor free space in CI before install steps.","Retry transient I/O errors once after diagnosing."],"tags":["go-toolchain","build","filesystem","io","install"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}