sxyazi/yazi · error
Failed to work on: : remote file has changed during upload
Error message
Failed to work on: {task:?}: remote file has changed during upload What it means
During the final phase of an upload, yazi-scheduler re-hashes the original source file and compares its signature hash against the stamp taken before transfer began. If the hashes differ, the source was modified concurrently, so the scheduler aborts the upload (before renaming the temp file into place) to avoid persisting inconsistent or clobbered data.
Solutions
- Stop processes writing to the source file, then retry the upload
- Upload a stable snapshot: copy the file to a temp location and upload that
- Retry the upload — if the file is now quiescent the hash will match
- For continuously-written files (logs), use rotation or flush-then-upload sequencing
Example fix
// before
std::fs::copy("/var/log/app.log", "/tmp/upload-staging")?; // file keeps growing
// after
let snapshot = std::fs::read("/var/log/app.log")?; // take a point-in-time copy
std::fs::write("/tmp/upload-staging", &snapshot)?; Defensive patterns
Strategy: retry
Validate before calling
// Compare file size/mtime before and after to detect concurrent modification early let before = std::fs::metadata(path)?; // ... upload ... let after = std::fs::metadata(path)?; assert_eq!(before.len(), after.len(), "file modified during upload");
Try / catch
match upload_result {
Err(e) if e.to_string().contains("remote file has changed during upload") => {
backoff_retry(upload, 3);
}
other => other,
} Prevention
- Quiesce writers (close editors, stop log tailing) before uploading
- Upload point-in-time snapshots instead of live files
- Use file locking where possible
- Keep uploads short to shrink the race window
When it happens
Trigger: The file being uploaded is modified (written, appended, truncated) by another process or user while the upload loop is still streaming data; the post-transfer hash `stamp.sig()` then mismatches `cha.hash_u128_str()` of the freshly stat'ed source.
Common situations: Editing a file in an editor that writes in-place while it's being uploaded to a remote; log files actively appended to during upload; sync tools or CI scripts touching the same file concurrently.
Related errors
- atime not available
- btime not available
- Cannot create file at root
- Cannot read cache stamp
- Cannot write cache stamp
AI-assisted analysis of sxyazi/yazi@a541adde4e (2026-09-02).
Data as JSON: /api/errors/96fb02306a249e20.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-scheduler/src/file/file.rs:450
ctx!(task, Transaction::tmp(&task.target).await, "Cannot determine temporary upload path")?;
let mut rx = ctx!(
task,
engine::copy(cache, &tmp, Attrs {
mode: Some(cha.mode),
atime: None,
btime: None,
mtime: None,
})
.await
)?;
loop {
match rx.recv().await.unwrap_or(Ok(0)) {
Ok(0) => {
let cha =
ctx!(task, Self::cha(&task.target, true, None).await, "Cannot stat original file")?;
if stamp.sig() != cha.hash_u128_str(&mut [0; 26]) {
Err(anyhow!("Failed to work on: {task:?}: remote file has changed during upload"))?;
}
ctx!(task, engine::rename(&tmp, &task.target).await, "Cannot persist uploaded file")?;
let cha =
ctx!(task, Self::cha(&task.target, true, None).await, "Cannot stat uploaded file")?;
ctx!(task, Stamp::write(cha, task.target.as_url()).await)?;
break;
}
Ok(n) => self.ops.out(task.id, FileOutUploadDo::Adv(n)),
Err(e) => ctx!(task, Err(e))?,
}
}
Ok(self.ops.out(task.id, FileOutUploadDo::Succ))
}
pub(super) async fn cha<U>(url: U, follow: bool, dent: Option<DirEntry>) -> io::Result<Cha>View on GitHub (pinned to a541adde4e)