herdrdev/herdr · error

failed to create private herdr remote download directory

Error message

failed to create private herdr remote download directory

What it means

Herdr creates a private temp download directory by retrying create_dir with random names, treating AlreadyExists as a retry signal. If retries exhaust with the directory still colliding (or a final attempt returns AlreadyExists), this AlreadyExists error is surfaced, meaning it could not obtain a unique private directory.

Source

Thrown at src/remote/attach.rs:1574

}

fn private_download_dir(asset_key: &str) -> io::Result<PathBuf> {
    let base = crate::platform::remote_private_temp_base();
    fs::create_dir_all(&base)?;
    for attempt in 0..100 {
        let dir = base.join(format!(
            "herdr-remote-{}-{}-{attempt}",
            std::process::id(),
            asset_key
        ));
        match crate::platform::create_remote_private_dir(&dir) {
            Ok(()) => return Ok(dir),
            Err(err) if err.kind() == io::ErrorKind::AlreadyExists => continue,
            Err(err) => return Err(err),
        }
    }

    Err(io::Error::new(
        io::ErrorKind::AlreadyExists,
        "failed to create private herdr remote download directory",
    ))
}

fn confirm_remote_install(
    target: &str,
    remote_herdr: &RemoteHerdr,
    source_description: &str,
) -> io::Result<()> {
    if !io::stdin().is_terminal() {
        return Err(io::Error::other(format!(
            "matching remote herdr {} is not installed at {}; run from an interactive terminal to approve installation",
            current_version(),
            remote_herdr.shell_path
        )));
    }

View on GitHub (pinned to f457cff4f2)

Solutions

  1. Set TMPDIR to a clean writable directory and retry
  2. Free space / repair /tmp if it is full or corrupted
  3. Check permissions on the temp directory root

Example fix

# before
export TMPDIR=/nonexistent_or_full_dir
# after
export TMPDIR=/tmp && herdr remote attach ...
Defensive patterns

Strategy: fallback

Validate before calling

let tmp = std::env::temp_dir();
if std::fs::metadata(&tmp).map(|m| m.is_dir()).unwrap_or(false) {
    // writable temp root available
}

Try / catch

match create_private_download_dir() {
    Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {
        std::fs::create_dir_all(std::env::temp_dir().join("herdr-dl"))
    }
    r => r,
}

Prevention

When it happens

Trigger: Extremely unlikely random-name collisions, a hostile or full tmpfs where every create returns AlreadyExists, or a tampered TMPDIR pointing at a read-only/existing structure causing repeated AlreadyExists results.

Common situations: TMPDIR misconfigured to a weird path, /tmp exhausted or replaced, or test environments looping creation.

Related errors


AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28). Data as JSON: /api/errors/46b4ffa6280b5dcc. Report an issue: GitHub.