{"record":{"id":"a1c360e162f5c677","repo":"zed-industries/zed","slug":"destination-path-has-no-parent-destination-path","errorCode":null,"errorMessage":"destination path has no parent: {destination_path:?}","messagePattern":"destination path has no parent: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/http_client/src/github_download.rs","lineNumber":52,"sourceCode":"        let metadata_content = serde_json::to_string(self)\n            .with_context(|| format!(\"serializing metadata for {metadata_path:?}\"))?;\n        async_fs::write(metadata_path, metadata_content.as_bytes())\n            .await\n            .with_context(|| format!(\"writing metadata file at {metadata_path:?}\"))?;\n        Ok(())\n    }\n}\n\npub async fn download_server_binary(\n    http_client: &dyn HttpClient,\n    url: &str,\n    digest: Option<&str>,\n    destination_path: &Path,\n    asset_kind: AssetKind,\n) -> Result<(), anyhow::Error> {\n    log::info!(\"downloading github artifact from {url}\");\n    let Some(destination_parent) = destination_path.parent() else {\n        anyhow::bail!(\"destination path has no parent: {destination_path:?}\");\n    };\n\n    let staging_path = staging_path(destination_parent, asset_kind)?;\n    let mut response = http_client\n        .get(url, Default::default(), true)\n        .await\n        .with_context(|| format!(\"downloading release from {url}\"))?;\n    let body = response.body_mut();\n\n    if let Err(err) = extract_to_staging(body, digest, url, &staging_path, asset_kind).await {\n        cleanup_staging_path(&staging_path, asset_kind).await;\n        return Err(err);\n    }\n\n    if let Err(err) = finalize_download(&staging_path, destination_path).await {\n        cleanup_staging_path(&staging_path, asset_kind).await;\n        return Err(err);\n    }","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/http_client/src/github_download.rs#L34-L70","documentation":"download_server_binary needs a parent directory next to the destination to create a staging path (for extraction/verification before an atomic rename). Rust's Path::parent() returns None only for the empty path and the filesystem root '/', so this bail fires when destination_path is '' or '/'.","triggerScenarios":"Passing destination_path = Path::new(\"\") or Path::new(\"/\") — e.g. a joined path where every component was empty because a config dir resolved to None and was silently stringified, or an install root mistakenly given as the destination itself.","commonSituations":"HOME/environment variables unset so paths::data_dir()-style lookups produce empty strings; misconfigured install prefixes set to '/'; test code passing a bare filename placeholder instead of a full path.","solutions":["Build the destination from a guaranteed base: PathBuf::from(env::var_os(\"HOME\").ok_or(...)?).join(\"...\")","Validate destination_path is absolute, non-empty, and not the root before calling download_server_binary","Log the offending path at the call site so the misconfigured variable is obvious","Check the configuration source (settings file / env) that produced the empty path"],"exampleFix":"// before\nlet destination_path = Path::new(&config.install_dir);\ndownload_server_binary(&http, url, digest, destination_path, asset_kind).await?;\n\n// after\nlet base = dirs::data_dir().context(\"no data dir\")?;\nlet destination_path = base.join(\"server\").join(binary_file_name);\nassert!(destination_path.parent().is_some(), \"invalid destination\");\ndownload_server_binary(&http, url, digest, &destination_path, asset_kind).await?;","handlingStrategy":"validation","validationCode":"fn valid_destination(path: &Path) -> bool {\n    !path.as_os_str().is_empty() && path.parent().is_some() && path != Path::new(\"/\")\n}\nassert!(valid_destination(&destination_path));","typeGuard":"fn is_concrete_file_path(p: &Path) -> bool {\n    p.parent().is_some() // false for \"\" and \"/\"\n}","tryCatchPattern":null,"preventionTips":["Always construct destinations via PathBuf::join from a validated base directory","Fail fast when HOME/XDG_DATA_HOME lookups return None instead of stringifying empty values","Unit-test path construction for empty/missing environment variables"],"tags":["filesystem","path","download","staging","validation"],"backgroundTag":"invalid-file-path","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}