{"record":{"id":"d9058c35de2071af","repo":"golangci/golangci-lint","slug":"stat-source-file-w","errorCode":null,"errorMessage":"stat source file: %w","messagePattern":"stat source file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/builder.go","lineNumber":219,"sourceCode":"\t\treturn fmt.Errorf(\"%s: %w\", strings.Join(cmd.Args, \" \"), err)\n\t}\n\n\treturn nil\n}\n\nfunc (b Builder) copyBinary(binaryName string) error {\n\tsrc := filepath.Join(b.repo, binaryName)\n\n\tsource, err := os.Open(filepath.Clean(src))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open source file: %w\", err)\n\t}\n\n\tdefer func() { _ = source.Close() }()\n\n\tinfo, err := source.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"stat source file: %w\", err)\n\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 {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/builder.go#L201-L237","documentation":"copyBinary calls source.Stat() after opening the binary to learn its mode bits for the destination file. This error wraps a failure of that stat call. Since the handle is already open, failure here is rare and usually indicates the file vanished mid-operation or an I/O error on the underlying filesystem.","triggerScenarios":"os.Open succeeded on b.repo/<binaryName> but source.Stat() returned an error: the file was removed or renamed after opening (delete-during-build race), the file sits on a failing/removable filesystem, or an unusual filesystem type rejects fstat.","commonSituations":"Concurrent builds cleaning the same output directory, CI where a later pipeline stage deletes artifacts early, network mounts (NFS) dropping stale handles, or /tmp cleanup daemons removing files mid-copy.","solutions":["Re-run the build — a transient race is the most common cause; ensure no concurrent process deletes the artifact","Serialize build/copy steps so nothing cleans the output directory between go build and copyBinary","Check filesystem health (dmesg / mount status) if the binary lives on a network or removable volume","Inspect the wrapped *os.PathError errno to confirm which syscall/condition failed"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-open sanity check\nif _, err := os.Stat(filepath.Join(b.repo, binaryName)); err != nil {\n    return fmt.Errorf(\"artifact vanished before copy: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := retry(3, func() error { return b.copyBinary(name) }) // safe: copy truncates dst\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) {\n        log.Fatalf(\"stat failed on %s: %v — check for concurrent deletion or filesystem faults\", perr.Path, perr.Err)\n    }\n    return err\n}","preventionTips":["Ensure no concurrent process cleans the build output during Build","Avoid building/copying on flaky network or removable volumes","Serialize build stages in CI to prevent artifact deletion mid-copy"],"tags":["go","file-io","stat","race"],"backgroundTag":"file-stat-failed","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}