sxyazi/yazi · error
Failed to work on : source of symlink doesn't exist
Error message
Failed to work on {task:?}: source of symlink doesn't exist What it means
A file task in yazi-scheduler's download worker was dispatched for a file whose `cha.is_orphan()` is true — i.e. the entry is a symlink whose source (target) does not exist. The scheduler refuses to proceed because there is nothing to download/read through a dangling symlink, so it surfaces the task itself in the message.
Solutions
- Verify the symlink target exists before queueing the download task
- Refresh the directory in the UI so the dangling symlink is marked orphaned and skip it
- Recreate or repoint the symlink target, then retry the task
- If writing custom plugin code, check `file.cha.is_orphan()` before scheduling downloads
Example fix
// before
self.requeue(task, LOW); // blindly retries orphaned symlink downloads
// after
if cha.is_orphan() {
self.ops.fail(id, "symlink target missing, skipping");
} else {
self.requeue(task, LOW);
} Defensive patterns
Strategy: validation
Validate before calling
if file.cha.is_orphan() {
eprintln!("skipping {}: symlink target missing", file.urn());
return;
}
queue_download(file); Try / catch
match scheduler_result {
Err(e) if e.to_string().contains("source of symlink doesn't exist") => refresh_and_skip(),
Err(e) => return Err(e),
Ok(v) => Ok(v),
} Prevention
- Check is_orphan() before queueing symlink entries
- Refresh directory listings after external filesystem changes
- Avoid downloading dangling symlinks; resolve targets first
When it happens
Trigger: A download task is created for a symlink entry whose link target was deleted or moved after the task was queued; the worker then evaluates `cha.is_orphan()` on the fetched FileAttrs and returns Err instead of downloading.
Common situations: User queues a symlink for download/copy, then removes the target file before the task runs; remote (SFTP/ultramarine-style) filesystems where the link target vanishes due to network refresh; stale file lists in the UI pointing at deleted targets.
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/6afbbf9c98c7d965.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-scheduler/src/file/file.rs:342
pub(crate) async fn trash_do(&self, task: FileInTrash) -> Result<(), FileOutTrash> {
ctx!(task, engine::trash(&task.target).await)?;
Ok(self.ops.out(task.id, FileOutTrash::Succ))
}
pub(crate) async fn download(&self, task: FileInDownload) -> Result<(), FileOutDownload> {
let id = task.id;
super::traverse::<FileOutDownload, _, _, _, _, _>(
task,
async |dir| {
let dir = dir.to_owned();
tokio::task::spawn_blocking(move || _ = Cwd::ensure(dir.as_url())).await.ok();
Ok(())
},
async |task, cha| {
Ok(if cha.is_orphan() {
Err(anyhow!("Failed to work on {task:?}: source of symlink doesn't exist"))?
} else {
self.ops.out(id, FileOutDownload::New(cha.len));
self.requeue(task, LOW);
})
},
|err| {
self.ops.out(id, FileOutDownload::Deform(err));
},
)
.await?;
Ok(self.ops.out(id, FileOutDownload::Succ))
}
pub(crate) async fn download_do(
&self,
mut task: FileInDownload,
) -> Result<(), FileOutDownloadDo> {View on GitHub (pinned to a541adde4e)