tonhowtf/omniget · error · anyhow::Error
is in use by another process ( ). Wait for active downloads…
Error message
{} is in use by another process ({}). Wait for active downloads to finish or cancel them, then try again. What it means
Thrown by replace_managed_binary on Windows when renaming the existing target binary to '<name>.old' fails, which almost always means the file is locked by a running process. The temp download is cleaned up and a user-actionable message is returned telling them to stop active downloads/processes.
Solutions
- Cancel/wait for all active downloads and any spawned ffmpeg/yt-dlp processes, then retry the update.
- Kill lingering ffmpeg.exe processes (Task Manager or taskkill /IM ffmpeg.exe).
- Temporarily exclude the app's binary directory from antivirus scanning if AV keeps the handle.
- Restart the app so it no longer holds inherited handles, then update.
Example fix
// before (caller) update_ffmpeg().await?; // fails while a download is running // after wait_for_idle_downloads().await; update_ffmpeg().await?;
Defensive patterns
Strategy: validation
Validate before calling
// Windows: fail fast (or wait) when the binary is still running
#[cfg(windows)]
fn binary_idle(target: &std::path::Path) -> bool {
match std::fs::rename(target, target.with_file_name(".probe_lock")) {
Ok(()) => { let _ = std::fs::rename(target.with_file_name(".probe_lock"), target); true }
Err(_) => false,
}
} Try / catch
match replace_managed_binary(&temp, &target).await {
Ok(()) => {},
Err(e) if format!("{e}").contains("in use by another process") => {
wait_for_active_downloads().await;
replace_managed_binary(&temp, &target).await?;
}
Err(e) => return Err(e),
} Prevention
- Gate binary updates on 'no active downloads/spawned ffmpeg' state.
- Track and reap child ffmpeg/yt-dlp processes before updating.
- Document the '.old' rollback mechanism so users know a failed update is safe to retry.
When it happens
Trigger: download_ffmpeg -> replace_managed_binary on Windows with cfg!(windows): the old ffmpeg.exe (or other managed binary) is currently executing or memory-mapped by this app, yt-dlp, antivirus, or another process, so fs::rename(target, .old) fails with a sharing/lock error.
Common situations: Updating ffmpeg while a download that shells out to it is running; antivirus holding a handle on the exe; the app itself spawned ffmpeg and hasn't reaped it; another instance of the app running.
Related errors
- Failed to replace
- Failed to replace file after 3 attempts
- Download reported success but no matching file appeared in
- pasta de origem não encontrada
- não achei nenhum StreamingHistory_*.json /…
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/26a5a08e84b644b6.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/dependencies.rs:344
target: &std::path::Path,
) -> anyhow::Result<()> {
if !target.exists() {
std::fs::rename(temp, target)
.map_err(|e| anyhow!("Failed to move {} into place: {}", target.display(), e))?;
return Ok(());
}
if cfg!(windows) {
let file_name = target
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("binary")
.to_string();
let old = target.with_file_name(format!("{}.old", file_name));
let _ = std::fs::remove_file(&old);
if let Err(e) = std::fs::rename(target, &old) {
let _ = std::fs::remove_file(temp);
return Err(anyhow!(
"{} is in use by another process ({}). Wait for active downloads to finish or cancel them, then try again.",
file_name,
e
));
}
if let Err(e) = std::fs::rename(temp, target) {
let _ = std::fs::rename(&old, target);
let _ = std::fs::remove_file(temp);
return Err(anyhow!("Failed to replace {}: {}", file_name, e));
}
let _ = std::fs::remove_file(&old);
Ok(())
} else {
std::fs::rename(temp, target)
.map_err(|e| anyhow!("Failed to replace {}: {}", target.display(), e))?;
Ok(())
}
}View on GitHub (pinned to 8600b91f42)