tonhowtf/omniget · error · anyhow::Error
Failed to replace file
Error message
Failed to replace file
What it means
After the 3-attempt rename loop, embed_metadata() checks a rename_ok flag. If all attempts returned Ok(()) from fs::rename but the flag was never set true (the loop's success path logs/sets flags but a code path left it false), this error fires and the temp file is removed. It is a defensive invariant check on the retry loop.
Solutions
- Inspect the rename loop: every Ok(()) branch must set rename_ok = true (or restructure to return directly on success).
- Prefer returning Ok(()) immediately inside the successful rename branch instead of tracking a flag.
- If reproduced at runtime, verify no concurrent task renames the same temp file concurrently.
- Add a unit test covering the loop's Ok and Err paths to keep the invariant intact.
Example fix
// before
if !rename_ok {
let _ = std::fs::remove_file(&temp_output);
return Err(anyhow!("Failed to replace file"));
}
// after
// in the retry loop, return directly on success instead of a flag:
Ok(()) => {
let _ = std::fs::remove_file(&temp_output).ok(); // nothing to clean
return Ok(());
}
// then the trailing unreachable check can be removed entirely Defensive patterns
Strategy: try-catch
Try / catch
match embed_metadata(/* ... */).await {
Err(e) if e.to_string() == "Failed to replace file" => {
// invariant trip in the rename loop; report with debug info
report_internal_bug(e);
}
other => other?,
} Prevention
- Return directly from the success branch of the rename loop instead of a flag
- Unit-test both Ok and Err paths of the rename retry loop
- Never mutate the rename loop's control flow without re-checking the trailing guard
When it happens
Trigger: The retry loop exhausts attempts where each rename returned Ok but did not set rename_ok=true (a logic bug), or a future refactor introduces a break/continue that skips setting the flag — the invariant check then trips.
Common situations: Surfacing during code changes to the retry loop rather than in normal operation; extremely rare in the wild because a successful rename sets the flag on the first attempt.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to replace file after 3 attempts
- {}
- FFmpeg not found in Flatpak sandbox
- Downloaded file from
- FFmpeg binary not found after extraction
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/649f334c5abcc644.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/ffmpeg.rs:564
}
Err(e) if attempt < 2 => {
tracing::warn!(
"Failed to replace file (attempt {}): {}, retrying...",
attempt + 1,
e
);
tokio::time::sleep(std::time::Duration::from_millis(500 * (attempt as u64 + 1)))
.await;
}
Err(e) => {
let _ = std::fs::remove_file(&temp_output);
return Err(anyhow!("Failed to replace file after 3 attempts: {}", e));
}
}
}
if !rename_ok {
let _ = std::fs::remove_file(&temp_output);
return Err(anyhow!("Failed to replace file"));
}
Ok(())
}
async fn download_thumbnail(
client: &reqwest::Client,
url: &str,
dest_dir: &Path,
) -> anyhow::Result<std::path::PathBuf> {
let response = client
.get(url)
.send()
.await
.map_err(|e| anyhow!("Failed to download thumbnail: {}", e))?;
let content_type = response
.headers()View on GitHub (pinned to 8600b91f42)