sinelaw/fresh · error · io::Error (InvalidInput)
Cannot paste a directory into itself
Error message
Cannot paste a directory into itself
What it means
paste_one_fs_op refuses to copy/cut a directory into a destination located inside the source directory itself. If allowed, the paste loop would copy the source into its own subtree it is currently iterating, recursing forever until stack overflow or disk-full. It returns io::ErrorKind::InvalidInput with this message.
Solutions
- Choose a destination outside the source directory subtree
- Check dst.starts_with(src) for directories in caller code before issuing the paste and show the user a message
- For duplicates, generate a sibling name instead of a nested one
Example fix
// before
explorer.paste(src_dir, src_dir.join("copy"))?; // InvalidInput
// after
let dst = src_dir.parent().unwrap().join(format!("{} copy", src_dir.file_name().unwrap().to_string_lossy()));
explorer.paste(src_dir, dst)?; Defensive patterns
Strategy: validation
Validate before calling
fn paste_is_safe(src: &Path, dst: &Path, src_is_dir: bool) -> bool {
!src_is_dir || !dst.starts_with(src)
} Try / catch
match explorer.paste(src, dst) { Err(e) if e.kind() == io::ErrorKind::InvalidInput => ui.show_message("Cannot paste a folder into itself"), other => other?, } Prevention
- Validate destination is not inside source before initiating any directory copy
- In UI, disable drop targets that are descendants of the drag source
- For duplicates, always generate sibling paths, never nested ones
When it happens
Trigger: Calling execute_resolved_multi_paste, perform_file_explorer_paste, or file_explorer_duplicate where the destination path starts_with the source path and the source is a directory — e.g. copying /data and pasting into /data/sub, or duplicating a folder into itself.
Common situations: User drags a folder into one of its own subfolders in the file explorer; paste target resolved to a path inside the copied tree; scripted bulk paste with generated destination paths.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- project path does not exist
- ${built.error}
- folder name must not be empty
- empty path
- buffer.cannot_open_directory
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/6694fd6aab76dd2c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/src/app/file_explorer.rs:1310
}
self.active_window_mut().key_context = KeyContext::FileExplorer;
}
/// Move or copy a single item at the filesystem level. No tree or UI
/// state is touched — callers are responsible for refreshing the
/// explorer afterwards.
fn paste_one_fs_op(&self, src: &Path, dst: &Path, is_cut: bool) -> PasteOpOutcome {
let src_is_dir = self.authority().filesystem.is_dir(src).unwrap_or(false);
// Guard against pasting a directory into itself or into one of its
// own descendants. Without this, `copy_dir_all(/d, /d/d)` would
// create `/d/d`, then iterate `/d` — which now contains the
// just-created `/d/d` — and recurse forever until stack overflow
// or disk-full. The check applies only when the source is a
// directory; file-into-itself is already handled by the
// same-location check in `file_explorer_paste`.
if src_is_dir && dst.starts_with(src) {
return PasteOpOutcome::Failed(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Cannot paste a directory into itself",
));
}
if is_cut {
// Try rename first (works if same filesystem). Only fall back to
// copy+delete for cross-device errors — any other rename failure
// (permission denied, etc.) must surface as-is so we don't
// silently succeed via a different codepath.
match self.authority().filesystem.rename(src, dst) {
Ok(()) => PasteOpOutcome::Ok,
Err(e) if e.kind() == std::io::ErrorKind::CrossesDevices => {
let copy_result = if src_is_dir {
self.authority().filesystem.copy_dir_all(src, dst)
} else {
self.authority().filesystem.copy(src, dst).map(|_| ())
};View on GitHub (pinned to 67894ca546)