yorukot/superfile · error

failed to copy: %w

Error message

failed to copy: %w

What it means

When the source and destination are on different partitions (or os.Rename failed), moveElement falls back to copying via copyElement and then deleting the source; this error wraps any copy failure. The root cause (permission, disk full, missing source) is in the wrapped error chain.

Source

Thrown at src/internal/file_operations.go:66

func moveElement(src, dst string) error {
	// Check if source and destination are on the same partition
	sameDev, err := isSamePartition(src, dst)
	if err != nil {
		return fmt.Errorf("failed to check partitions: %w", err)
	}

	// If on the same partition, attempt to rename (which will use the same inode)
	if sameDev {
		if err = os.Rename(src, dst); err == nil {
			return nil
		}
		// If rename fails, fall back to copy+delete
	}

	// If on different partitions or rename failed, fall back to copy+delete
	err = copyElement(src, dst)
	if err != nil {
		return fmt.Errorf("failed to copy: %w", err)
	}

	err = os.RemoveAll(src)
	if err != nil {
		return fmt.Errorf("failed to remove source after copy: %w", err)
	}

	return nil
}

// copyElement handles copying of both files and directories
func copyElement(src, dst string) error {
	srcInfo, err := os.Stat(src)
	if err != nil {
		return fmt.Errorf("failed to stat source: %w", err)
	}

	if srcInfo.IsDir() {

View on GitHub (pinned to b72f550bc6)

Solutions

  1. Inspect the wrapped error for the true cause (stat vs write failure).
  2. Check free space on the destination (df -h) — ENOSPC is common on cross-partition moves.
  3. Verify the destination directory exists and is writable.
  4. Confirm the source still exists and is readable before moving.

Example fix

// before
moveElement("/home/data", "/mnt/full-disk/data") // ENOSPC
// after
// free space or choose another destination
moveElement("/home/data", "/mnt/other/data")
Defensive patterns

Strategy: try-catch

Validate before calling

srcInfo, err := os.Stat(src)
if err != nil { return fmt.Errorf("source missing: %w", err) }
if st, err := os.Stat(filepath.Dir(dst)); err != nil || !st.IsDir() {
    return fmt.Errorf("destination parent must be an existing writable dir")
}
// optional: free-space check via syscall.Statfs on dst volume

Type guard

func isWritableDir(p string) bool {
    st, err := os.Stat(p)
    return err == nil && st.IsDir()
}

Try / catch

if err := moveElement(src, dst); err != nil {
    if strings.Contains(err.Error(), "failed to copy") {
        log.Errorf("cross-partition move failed: %v", err)
        // keep source intact; surface ENOSPC/EACCES to the user
        return err
    }
    return err
}

Prevention

When it happens

Trigger: moveElement(src, dst) where copyElement fails: os.Stat fails on src, directory creation or file copy fails on dst (ENOENT parent, EACCES, ENOSPC).

Common situations: Moving across drives to a full destination disk; destination directory not writable; source disappeared between the rename attempt and the copy; copying a directory containing unreadable entries.

Related errors


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