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
- Inspect the wrapped error for the true cause (stat vs write failure).
- Check free space on the destination (df -h) — ENOSPC is common on cross-partition moves.
- Verify the destination directory exists and is writable.
- 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
- Check destination free space before large cross-partition moves.
- Ensure the destination directory exists and is writable beforehand.
- Verify the source exists immediately before initiating the move.
- For very large trees, consider copy-with-progress so failures are resumable.
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
- failed to check partitions: %w
- failed to remove source after copy: %w
- failed to stat source: %w
- failed to create destination directory: %w
- failed to read source directory: %w
AI-assisted analysis of yorukot/superfile@b72f550bc6 (2026-09-01).
Data as JSON: /api/errors/8414d215d040ab14.
Report an issue: GitHub.