{"record":{"id":"5cbd0f224fc511c1","repo":"golangci/golangci-lint","slug":"copy-source-to-destination-w","errorCode":null,"errorMessage":"copy source to destination: %w","messagePattern":"copy source to destination: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/builder.go","lineNumber":238,"sourceCode":"\t}\n\n\tif b.cfg.Destination != \"\" {\n\t\terr = os.MkdirAll(b.cfg.Destination, os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create destination directory: %w\", err)\n\t\t}\n\t}\n\n\tdst, err := os.OpenFile(filepath.Join(b.cfg.Destination, binaryName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create destination file: %w\", err)\n\t}\n\n\tdefer func() { _ = dst.Close() }()\n\n\t_, err = io.Copy(dst, source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"copy source to destination: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (b Builder) getBinaryName() string {\n\tname := b.cfg.Name\n\tif runtime.GOOS == \"windows\" {\n\t\tname += \".exe\"\n\t}\n\n\treturn name\n}\n\nfunc (b Builder) createVersion(orig string) (string, error) {\n\thash := sha256.New()\n\n\tfor _, plugin := range b.cfg.Plugins {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/builder.go#L220-L256","documentation":"copyBinary streams the binary with io.Copy(dst, source); this error wraps any failure of that copy. Since both handles are already open, failures come from the write side (disk full, quota) or the read side (source became unreadable), plus any flush/write error at the OS level.","triggerScenarios":"io.Copy returned an error mid-transfer: destination filesystem full or over quota, source file truncated/replaced during read, I/O error on either volume, or process resource limits (RLIMIT_FSIZE) hit while writing.","commonSituations":"CI runner with small ephemeral disk copying large binaries, quota-limited home directories, NFS/network destination dropping mid-write, or disk-full during a release upload step.","solutions":["Free disk space on the destination volume (df -h) or point Destination at a volume with enough room","Check the source binary size and integrity; rebuild if it may be truncated","Re-run the copy after resolving the I/O condition — the destination file is truncated by O_TRUNC so a retry is safe","Check quotas (quota -s) and process limits (ulimit -f) if writes stop at a consistent size","Inspect the wrapped error: it names the failing side (read from source vs write to dst path)"],"exampleFix":"// before\n# destination volume 95% full during release\n// after\ndf -h /release && go build clean && retry Build with Destination on a volume with free space","handlingStrategy":"retry","validationCode":"src := filepath.Join(b.repo, binaryName)\ninfo, err := os.Stat(src)\nif err != nil { return err }\nvar st syscall.Statfs_t\nif err := syscall.Statfs(cfg.Destination, &st); err == nil {\n    free := st.Bavail * uint64(st.Bsize)\n    if free < uint64(info.Size())*2 {\n        return fmt.Errorf(\"only %d bytes free at %s, need ~%d\", free, cfg.Destination, info.Size()*2)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := retry(3, backoffExponential, func() error {\n    return b.copyBinary(name) // O_TRUNC makes each attempt start clean\n})\nif err != nil {\n    log.Fatalf(\"copy failed after retries: %v — check disk space and quotas\", err)\n}","preventionTips":["Check df -h on the destination volume before large release copies","Retry copies: io.Copy failures on full disks are often transient once space is freed","Watch disk quotas and RLIMIT_FSIZE in CI containers","Verify source artifact size/integrity after the build"],"tags":["go","io-copy","disk-full","file-io"],"backgroundTag":"no-space-left-on-device","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}