golangci/golangci-lint · error
stat source file: %w
Error message
stat source file: %w
What it means
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.
Source
Thrown at pkg/commands/internal/builder.go:219
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) copyBinary(binaryName string) error {
src := filepath.Join(b.repo, binaryName)
source, err := os.Open(filepath.Clean(src))
if err != nil {
return fmt.Errorf("open source file: %w", err)
}
defer func() { _ = source.Close() }()
info, err := source.Stat()
if err != nil {
return fmt.Errorf("stat source file: %w", err)
}
if b.cfg.Destination != "" {
err = os.MkdirAll(b.cfg.Destination, os.ModePerm)
if err != nil {
return fmt.Errorf("create destination directory: %w", err)
}
}
dst, err := os.OpenFile(filepath.Join(b.cfg.Destination, binaryName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode())
if err != nil {
return fmt.Errorf("create destination file: %w", err)
}
defer func() { _ = dst.Close() }()
_, err = io.Copy(dst, source)
if err != nil {View on GitHub (pinned to ed7a235d2d)
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
Defensive patterns
Strategy: retry
Validate before calling
// pre-open sanity check
if _, err := os.Stat(filepath.Join(b.repo, binaryName)); err != nil {
return fmt.Errorf("artifact vanished before copy: %w", err)
} Try / catch
err := retry(3, func() error { return b.copyBinary(name) }) // safe: copy truncates dst
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) {
log.Fatalf("stat failed on %s: %v — check for concurrent deletion or filesystem faults", perr.Path, perr.Err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- open source file: %w
- create destination file: %w
- copy source to destination: %w
- file %s open: %w
- create destination directory: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/d9058c35de2071af.
Report an issue: GitHub.