can1357/oh-my-pi · error · LnError

extra operand {} Try '{} --help' for more information.

Error message

extra operand {}
Try '{} --help' for more information.

What it means

The ln builtin's ExtraOperand variant fires when more operands are supplied than the link mode accepts. In plain (non-directory-destination) mode ln takes exactly source and destination; a third or later operand triggers this coreutils-style message with a --help hint. The OsString is the offending extra operand and the String is the program name used in the hint.

Source

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

	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),
}


mod options {
	pub const FORCE: &str = "force";
	//pub const DIRECTORY: &str = "directory";
	pub const INTERACTIVE: &str = "interactive";
	pub const NO_DEREFERENCE: &str = "no-dereference";

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure the final operand is an existing directory when linking multiple sources
  2. Split into multiple ln calls, one per source/destination pair
  3. Remove the extra operand from the argument list

Example fix

// before
ln(&host, &["a.txt", "b.txt", "links/"])?; // if "links/" doesn't exist
// after
std::fs::create_dir("links")?; // or use explicit pairs
ln(&host, &["a.txt", "links/a.txt"])?;
ln(&host, &["b.txt", "links/b.txt"])?;
Defensive patterns

Strategy: validation

Validate before calling

fn validate_arity(args: &[&OsStr]) -> Result<(), &'static str> {
    match args.len() {
        2 => Ok( ),
        n if n > 2 => {
            let last = std::path::Path::new(args.last().unwrap());
            if last.is_dir() { Ok( ) } else { Err("multiple sources require a directory destination") }
        }
        _ => Err("need source and destination"),
    }
}

Try / catch

match ln(&host, args) {
    Err(e) if e.to_string().starts_with("extra operand") => eprintln!("pass at most SOURCE DEST, or end with an existing directory"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling ln with three or more path arguments without a directory destination, e.g. `ln a b c`.

Common situations: Scripts that join many files into one ln call expecting GNU's 'link all into directory' mode while the last argument is not a directory; typo'd extra path.

Related errors


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