{"record":{"id":"907f91f0e05907ad","repo":"tonhowtf/omniget","slug":"deno-binary-not-found-after-extraction","errorCode":null,"errorMessage":"Deno binary not found after extraction","messagePattern":"Deno binary not found after extraction","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/dependencies.rs","lineNumber":770,"sourceCode":"                .map_err(|e| anyhow!(\"Failed to read zip entry: {}\", e))?;\n\n            let name = file.name().to_string();\n            if name.ends_with(&deno_name_clone) || name == \"deno\" || name == \"deno.exe\" {\n                let dest = bin_dir_clone.join(&deno_name_clone);\n                let mut buf = Vec::new();\n                std::io::Read::read_to_end(&mut file, &mut buf)?;\n                std::fs::write(&dest, &buf)?;\n                break;\n            }\n        }\n\n        Ok::<(), anyhow::Error>(())\n    })\n    .await\n    .map_err(|e| anyhow!(\"Spawn blocking failed: {}\", e))??;\n\n    if !deno_target.exists() {\n        return Err(anyhow!(\"Deno binary not found after extraction\"));\n    }\n\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::PermissionsExt;\n        let _ = std::fs::set_permissions(&deno_target, std::fs::Permissions::from_mode(0o755));\n    }\n\n    #[cfg(target_os = \"macos\")]\n    {\n        let deno_mac = deno_target.clone();\n        let _ = tokio::task::spawn_blocking(move || {\n            crate::core::process::std_command(\"xattr\")\n                .args([\"-d\", \"com.apple.quarantine\"])\n                .arg(&deno_mac)\n                .output()\n        })\n        .await;","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/dependencies.rs#L752-L788","documentation":"Raised in download_deno after the zip extraction completes: deno_target (bin_dir/deno_name) does not exist on disk. The zip was processed but no entry matched the expected deno binary name (name ends with deno_name, or is exactly \"deno\"/\"deno.exe\"), so nothing was written to the target path.","triggerScenarios":"The downloaded Deno zip contains no entry matching the expected binary name for the current platform, or entry matching failed, leaving bin_dir/deno_name absent after extraction.","commonSituations":"Deno changed the archive layout in a new release; wrong deno_name computed for the target OS/arch; the match condition (ends_with deno_name, == \"deno\", == \"deno.exe\") misses entries inside a subdirectory with a different casing; the extraction silently skipped all entries.","solutions":["Log the zip entry names and compare with deno_name; loosen the match if the layout changed","Pin Deno to a version whose zip layout is known to work","Verify the correct platform-specific deno zip URL was downloaded","Ensure bin_dir exists and extraction wrote files (check create_dir_all and permissions)"],"exampleFix":"// before\nif name.ends_with(&deno_name_clone) || name == \"deno\" || name == \"deno.exe\" {\n// after\nlet base = name.rsplit('/').next().unwrap_or(&name);\nif base == deno_name_clone || base == \"deno\" || base == \"deno.exe\" {","handlingStrategy":"validation","validationCode":"// verify the expected binary exists after extraction, with a diagnostic\nif !deno_target.exists() {\n    let entries: Vec<String> = archive\n        .file_names()\n        .unwrap_or_default()\n        .to_vec();\n    return Err(anyhow!(\n        \"Deno binary not found after extraction; zip contained: {:?}\",\n        entries\n    ));\n}","typeGuard":"fn deno_binary_present(bin_dir: &std::path::Path, deno_name: &str) -> bool {\n    bin_dir.join(deno_name).is_file()\n}","tryCatchPattern":"match std::fs::metadata(&deno_target) {\n    Ok(m) if m.is_file() && m.len() > 0 => { /* proceed to chmod */ }\n    _ => return Err(anyhow!(\n        \"Deno binary missing after extraction; check zip layout for {}\",\n        deno_name\n    )),\n}","preventionTips":["Log all zip entry names during extraction to catch layout changes in new Deno releases","Match on the entry basename (after the last '/') rather than the full path suffix","Pin the Deno version so archive layout cannot change unexpectedly","Verify file size > 0 after writing the binary"],"tags":["deno","extraction","file-not-found","bootstrap"],"backgroundTag":"file-not-found","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}