yorukot/superfile · error
failed to read source directory: %w
Error message
failed to read source directory: %w
What it means
After creating the destination directory, copyDir reads the source's entries with os.ReadDir(src); failure is wrapped as 'failed to read source directory'. This means the source directory exists (it was stat'd) but cannot be listed — typically a permissions problem or it being replaced by a non-directory mid-operation.
Source
Thrown at src/internal/file_operations.go:99
return fmt.Errorf("failed to stat source: %w", err)
}
if srcInfo.IsDir() {
return copyDir(src, dst, srcInfo)
}
return copyFile(src, dst, srcInfo)
}
// copyDir recursively copies a directory
func copyDir(src, dst string, srcInfo os.FileInfo) error {
err := os.MkdirAll(dst, srcInfo.Mode())
if err != nil {
return fmt.Errorf("failed to create destination directory: %w", err)
}
entries, err := os.ReadDir(src)
if err != nil {
return fmt.Errorf("failed to read source directory: %w", err)
}
for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())
entryInfo, err := entry.Info()
if err != nil {
return fmt.Errorf("failed to get entry info: %w", err)
}
if entryInfo.IsDir() {
err = copyDir(srcPath, dstPath, entryInfo)
} else {
err = copyFile(srcPath, dstPath, entryInfo)
}
if err != nil {
return errView on GitHub (pinned to b72f550bc6)
Solutions
- Grant read permission on the source directory (chmod o+r / correct owner).
- Reconnect or remount the source volume if it dropped.
- Check the source is still a directory (concurrent modification) and retry.
- Copy with elevated privileges if system-level protection is intentional.
Example fix
// before drwx------ root root /data/secret // ReadDir fails as non-root // after chmod o+rx /data/secret // then retry the copy
Defensive patterns
Strategy: validation
Validate before calling
st, err := os.Stat(src)
if err != nil { return err }
if !st.IsDir() { return fmt.Errorf("%s is not a directory", src) }
probe, err := os.ReadDir(src) // cheap pre-check of readability
if err != nil { return fmt.Errorf("source not readable: %w", err) } Type guard
func dirReadable(src string) bool {
_, err := os.ReadDir(src)
return err == nil
} Try / catch
if err := copyElement(src, dst); err != nil {
var pErr *fs.PathError
if errors.As(err, &pErr) && errors.Is(pErr.Err, fs.ErrPermission) {
log.Errorf("Source dir %s unreadable — check permissions/mount", pErr.Path)
return err // or skip-and-report in batch copy
}
return err
} Prevention
- Verify directory read permission (r bit) before copying trees.
- Check mount health (network/USB) before long copy operations.
- Skip-and-report unreadable subdirectories instead of aborting the whole copy.
- Avoid mutating (deleting/renaming) the source tree while it is being copied.
When it happens
Trigger: copyElement -> copyDir where os.ReadDir(src) fails: no read permission on the directory, src is on an inaccessible mount, or src was swapped/removed concurrently after os.Stat.
Common situations: Copying a directory with mode 700 owned by another user; reading from a USB/network mount that dropped; racing deletion of the source tree during a paste; encrypted/protected directories.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- failed to create destination directory: %w
- failed to create destination file: %w
- failed to copy: %w
- failed to remove source after copy: %w
- failed to stat source: %w
AI-assisted analysis of yorukot/superfile@b72f550bc6 (2026-09-01).
Data as JSON: /api/errors/30f6ae02d761b66e.
Report an issue: GitHub.