can1357/oh-my-pi · error · LnError
{}: hard link not allowed for directory
Error message
{}: hard link not allowed for directory What it means
The ln builtin's FailedToCreateHardLinkDir variant fires when a hard link to a directory is requested. Most filesystems and POSIX forbid link(2) on directories (only root may, and even then most kernels refuse with EPERM), so the tool rejects it early with the quoted directory path.
Source
Thrown at crates/pi-builtins/src/ln.rs:68
#[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";
pub const SYMBOLIC: &str = "symbolic";
pub const LOGICAL: &str = "logical";
pub const PHYSICAL: &str = "physical";View on GitHub (pinned to 9690622007)
Solutions
- Use -s (symbolic link) for directories: `ln -s somedir somelink`
- Branch on file type: only hard-link regular files
- If a directory reference is needed, consider a symlink or bind mount instead
Example fix
// before ln(&host, &["mydir", "mydir-link"])?; // after ln(&host, &["-s", "mydir", "mydir-link"])?;
Defensive patterns
Strategy: validation
Validate before calling
fn ensure_not_dir(p: &Path) -> std::io::Result<()> {
let md = std::fs::symlink_metadata(p)?;
if md.is_dir() {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("{}: hard link not allowed for directory", p.display())));
}
Ok( )
} Type guard
fn is_regular_file(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.is_file()).unwrap_or(false)
} Try / catch
match ln(&host, args) {
Err(e) if e.to_string().contains("hard link not allowed for directory") => {
// fall back to symlink
ln(&host, &["-s", args[0], args[1]])?;
}
other => other?,
} Prevention
- Check the source type before hard-linking; directories need symlinks
- Remember link(2) is forbidden on directories on Linux/macOS regardless of privileges
When it happens
Trigger: Invoking `ln somedir somelink` (hard-link mode) where somedir is a directory and -s/--symbolic was not passed.
Common situations: Users intending a symlink but forgetting -s; scripts that portably link both files and dirs without branching on type.
Related errors
- Is a directory
- {} and {} are the same file
- missing destination file operand after {}
- extra operand {} Try '{} --help' for more information.
- {0}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/0129f083be7073cc.
Report an issue: GitHub.