rustdesk/rustdesk · error

Can't get parent directory of {src_raw}

Error message

Can't get parent directory of {src_raw}

What it means

copy_raw_cmd() builds an XCOPY command string to copy a directory tree. It takes the parent directory of src_raw via PathBuf::parent(); if that returns None (src_raw is a drive root or a degenerate path), the anyhow! error is returned. XCOPY needs a source directory, so a path without a parent cannot be processed.

Source

Thrown at src/platform/windows.rs:1471

    let mut path = get_reg_of(&subkey, "InstallLocation");
    if path.is_empty() {
        path = get_default_install_path();
    }
    path = path.trim_end_matches('\\').to_owned();
    let start_menu = format!(
        "%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\{}",
        crate::get_app_name()
    );
    let exe = format!("{}\\{}.exe", path, crate::get_app_name());
    (subkey, path, start_menu, exe)
}

pub fn copy_raw_cmd(src_raw: &str, _raw: &str, _path: &str) -> ResultType<String> {
    let main_raw = format!(
        "XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z",
        PathBuf::from(src_raw)
            .parent()
            .ok_or(anyhow!("Can't get parent directory of {src_raw}"))?
            .to_string_lossy()
            .to_string(),
        _path
    );
    return Ok(main_raw);
}

pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> ResultType<String> {
    let main_exe = copy_raw_cmd(src_exe, exe, path)?;
    Ok(format!(
        "
        {main_exe}
        copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
        ",
        ORIGIN_PROCESS_EXE = win_topmost_window::ORIGIN_PROCESS_EXE,
        broker_exe = win_topmost_window::INJECTED_PROCESS_EXE,
    ))
}

View on GitHub (pinned to 91c9fccbb0)

Solutions

  1. Validate src_raw with Path::new(src_raw).parent().is_some() (and that it exists) before calling copy_raw_cmd.
  2. Pass a subdirectory rather than a drive root as the source path.
  3. Canonicalize the path first (std::fs::canonicalize) so UNC prefixes and relative components don't produce degenerate parents.
  4. If a root copy is genuinely needed, rewrite the command to copy from the root directly instead of using parent().

Example fix

// before
let p = PathBuf::from(src_raw).parent().ok_or(anyhow!("..."))?;
// after
let src = std::fs::canonicalize(src_raw)?;
let p = src.parent().ok_or_else(|| anyhow!("src is a root path: {}", src.display()))?;
Defensive patterns

Strategy: validation

Validate before calling

fn src_copyable(src_raw: &str) -> bool {
    let p = std::path::Path::new(src_raw);
    p.is_dir() && p.parent().is_some()
}

Type guard

fn copyable_parent(src_raw: &str) -> Option<std::path::PathBuf> {
    std::path::Path::new(src_raw).parent().map(|p| p.to_path_buf())
}

Try / catch

match copy_raw_cmd(src_raw, dst, path) {
    Err(e) if e.to_string().contains("parent directory") => {
        log::error!("source path {:?} has no parent; use a subdirectory", src_raw);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling copy_raw_cmd(src_raw, ...) with a src_raw string whose PathBuf::parent() is None — a bare root like "C:\\", an empty/whitespace path, or a path with only a prefix.

Common situations: Passing the root of a drive as the update source directory, or passing a path that was never canonicalized/validated before building the command.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10). Data as JSON: /api/errors/68f5fa510a9161a5. Report an issue: GitHub.