yorukot/superfile · error

failed to open source file

Error message

failed to open source file: %w

What it means

copyFile wraps os.Open(src) failures when opening the source file for reading during a copy. Typical wrapped causes are ENOENT (file gone) and EACCES (no read permission). The copy of that single file fails immediately.

Solutions

  1. Verify the source file exists (ls or os.Stat) and re-select it if it was moved or deleted.
  2. Fix read permissions: chmod u+r (or chown) so the running user can read the file.
  3. If running with elevated context lost (e.g. sudo copy earlier), re-copy with correct ownership.
  4. Retry the paste; if it recurs, check for processes deleting files concurrently.

Example fix

// before
err := ops.CopyFile(srcPath, dstPath)
// after
if _, statErr := os.Stat(srcPath); errors.Is(statErr, fs.ErrNotExist) {
    return fmt.Errorf("source %s no longer exists; refresh selection and retry", srcPath)
}
if err := ops.CopyFile(srcPath, dstPath); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
        return fmt.Errorf("cannot read %s: fix permissions (%w)", srcPath, err)
    }
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(src)
if err != nil {
    return fmt.Errorf("source unavailable: %w", err)
}
if info.IsDir() {
    return fmt.Errorf("%s is a directory, not a file", src)
}
f, err := os.OpenFile(src, os.O_RDONLY, 0)
if err != nil {
    return fmt.Errorf("source not readable: %w", err)
}
f.Close()

Try / catch

if err := ops.CopyFile(src, dst); err != nil {
    if errors.Is(err, fs.ErrNotExist) { /* refresh selection */ }
    if errors.Is(err, fs.ErrPermission) { /* fix chmod */ }
    return err
}

Prevention

When it happens

Trigger: copyElement, copyDir or actualPasteOperation calls copyFile with a src path that was deleted after the directory listing, or a file the user cannot read (mode 0600 owned by another user, or read permission removed).

Common situations: Pasting files after the original was deleted or renamed; copying files with restrictive permissions; reading from a mount whose contents changed; a file locked/deleted by another process.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of yorukot/superfile@b72f550bc6 (2026-09-01). Data as JSON: /api/errors/de75e496f729ee34. Report an issue: GitHub.

Appendix: source

Thrown at src/internal/file_operations.go:140

// is an equivalent of "cp -P" command
func copyLinkFile(src, dst string) error {
	target, err := os.Readlink(src)
	if err != nil {
		return err
	}
	return os.Symlink(target, dst)
}

func isSymlink(info os.FileInfo) bool {
	return info.Mode()&os.ModeSymlink != 0
}

// copyFile copies a single file
func copyFile(src, dst string, srcInfo os.FileInfo) error {
	srcFile, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("failed to open source file: %w", err)
	}
	defer srcFile.Close()

	dstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, srcInfo.Mode())
	if err != nil {
		return fmt.Errorf("failed to create destination file: %w", err)
	}
	defer dstFile.Close()

	if _, err := io.Copy(dstFile, srcFile); err != nil {
		return fmt.Errorf("failed to copy file contents: %w", err)
	}
	return nil
}

// pasteDir handles directory copying with progress tracking
func pasteDir(src, dst string, p *processbar.Process, cut bool, processBarModel *processbar.Model) error {
	dst, err := renameIfDuplicate(dst)

View on GitHub (pinned to b72f550bc6)