can1357/oh-my-pi · error · LnError

{} and {} are the same file

Error message

{} and {} are the same file

What it means

The ln builtin's SameFile variant fires when the source and destination operands resolve to the same file. Creating a hard link or symlink to itself would either fail at the OS level or create a pointless self-referential link, so the tool rejects it up front with a GNU-coreutils-style message naming both quoted paths.

Source

Thrown at crates/pi-builtins/src/ln.rs:59

	verbose:        bool,
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum OverwriteMode {
	NoClobber,
	Interactive,
	Force,
}

#[derive(Error, Debug)]
enum LnError {
	#[error("target {} is not a directory", _0.quote())]
	TargetIsNotADirectory(PathBuf),

	#[error("")]
	SomeLinksFailed,

	#[error("{} and {} are the same file", _0.quote(), _1.quote())]
	SameFile(PathBuf, PathBuf),

	#[error("missing destination file operand after {}", _0.quote())]
	MissingDestination(PathBuf),

	#[error("extra operand {}\nTry '{} --help' for more information.", _0.quote(), _1)]
	ExtraOperand(OsString, String),

	#[error("{}: hard link not allowed for directory", _0.to_string_lossy())]
	FailedToCreateHardLinkDir(PathBuf),

	#[error("{0}")]
	Message(String),

	#[error("{0}")]
	Io(#[from] std::io::Error),
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Check that source and destination paths differ before invoking ln
  2. Use std::fs::canonicalize on both paths and compare before linking
  3. Fix the variable/script that supplies identical operands

Example fix

// before
ln(&host, &["file.txt", "file.txt"])?;
// after
if std::fs::canonicalize("file.txt")? == std::fs::canonicalize("file.txt")? {
    eprintln!("source and destination are the same file");
} else {
    ln(&host, &["file.txt", "file.txt"])?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_distinct(src: &Path, dst: &Path) -> std::io::Result<()> {
    if src == dst || std::fs::canonicalize(src)? == std::fs::canonicalize(dst)? {
        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "source and destination are the same file"));
    }
    Ok( )
}

Try / catch

match ln(&host, args) {
    Err(e) if e.to_string().contains("are the same file") => eprintln!("skip: source == destination"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling ln where source and destination are the same path (after canonicalization), e.g. `ln file.txt file.txt` or `ln dir/a dir/a`.

Common situations: Shell/variable interpolation mistakes where SRC and DST variables expand to the same value; scripts copying a file onto itself via a loop or config substitution.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/93f3041cff26bf45. Report an issue: GitHub.