can1357/oh-my-pi · error
{0} and {1} are the same file
Error message
{0} and {1} are the same file What it means
GNU-compatible `mv` error (`MvError::SameFile`, crates/pi-builtins/src/mv.rs:57), raised from `assert_not_same_file`. The source and target resolve to the same file — via canonicalized paths being equal, hardlink/symlink identity detection, or the source being `.` / ending in `/.` — so moving it onto itself is a no-op that `mv` refuses.
Source
Thrown at crates/pi-builtins/src/mv.rs:57
are_hardlinks_to_same_file, canonicalize, path_ends_with_terminator,
},
update_control::{self, UpdateMode},
};
use crate::host::{Host, Utility, format_usage, matches_parser, util};
#[cfg(unix)]
use self::hardlink::{
HardlinkGroupScanner, HardlinkOptions, HardlinkTracker, create_hardlink_context,
with_optional_hardlink_context,
};
#[derive(Debug, Error)]
enum MvError {
#[error("cannot stat {0}: No such file or directory")]
NoSuchFile(String),
#[error("cannot stat {0}: Not a directory")]
CannotStatNotADirectory(String),
#[error("{0} and {1} are the same file")]
SameFile(String, String),
#[error("cannot move {0} to a subdirectory of itself, {1}")]
SelfTargetSubdirectory(String, String),
#[error("cannot overwrite directory {0} with non-directory")]
DirectoryToNonDirectory(String),
#[error("cannot overwrite non-directory {1} with directory {0}")]
NonDirectoryToDirectory(String, String),
#[error("target {0}: Not a directory")]
NotADirectory(String),
#[error("target directory {0}: Not a directory")]
TargetNotADirectory(String),
#[error("failed to access {0}: Not a directory")]
FailedToAccessNotADirectory(String),
}
#[derive(Debug, Error)]
enum MvFailure {
#[error(transparent)]View on GitHub (pinned to 9690622007)
Solutions
- Skip the operation when paths are identical: compare canonical paths (`realpath`) before calling mv.
- Use distinct source and target names, e.g. `mv file file.bak` if a copy was intended (mv does not copy — use `cp`).
- Resolve symlinked directories so source and target no longer alias the same file.
- If the goal was moving into a directory, ensure the target is a different directory than the source's parent.
Example fix
# before mv "$file" "$OUT_DIR/$file" # OUT_DIR equals the file's dir -> same file # after src_real=$(realpath "$file"); dst_real=$(realpath -m "$OUT_DIR/$(basename "$file")") [ "$src_real" != "$dst_real" ] && mv "$file" "$OUT_DIR/" || echo "skipping: same file"
Defensive patterns
Strategy: validation
Validate before calling
[ "$(realpath "$src")" != "$(realpath -m "$dst")" ] || { echo "same file, skipping"; exit 0; } Try / catch
if ! mv "$src" "$dst" 2>err.txt; then grep -q 'are the same file' err.txt && exit 0; cat err.txt >&2; exit 1; fi
Prevention
- Compare canonicalized (realpath) source and target before moving.
- Never use mv to copy — use cp when a same-named copy is the goal.
- Beware symlinked directories making two spellings resolve to one file.
- Treat `.` and path/`/.` operands as always-invalid mv sources.
When it happens
Trigger: `mv file file`; `mv ../dir/file dir/file` (same file via different relative paths); `mv . subdir` or `mv dir/. other` (source is `.` or ends with `/.`); moving a file onto a hardlink to itself; `mv x dir` where `dir` is a symlink to the directory containing `x`.
Common situations: Scripts joining an absolute base with an already-absolute path (e.g. `mv "$f" "$PWD/$f"`); symlinked directories on PATH-like setups making target and source aliases; copy-paste commands where source and target were left identical; moving directories into themselves detected here before the distinct SelfTargetSubdirectory check.
Related errors
- {} and {} are the same file
- missing destination file operand after {}
- extra operand {} Try '{} --help' for more information.
- {}: hard link not allowed for directory
- {0}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/083d5e799f65c617.
Report an issue: GitHub.