{"record":{"id":"51f6f2d8e9f4e6b8","repo":"zed-industries/zed","slug":"file-was-deleted","errorCode":null,"errorMessage":"file was deleted","messagePattern":"file was deleted","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/fs/src/fs.rs","lineNumber":496,"sourceCode":"        anyhow::ensure!(result != -1, \"fcntl returned -1\");\n\n        // SAFETY: `fcntl` will initialize the path buffer.\n        let c_str = unsafe { CStr::from_ptr(path_buf.as_ptr().cast()) };\n        anyhow::ensure!(!c_str.is_empty(), \"Could find a path for the file handle\");\n        let path = PathBuf::from(OsStr::from_bytes(c_str.to_bytes()));\n        Ok(path)\n    }\n\n    #[cfg(target_os = \"linux\")]\n    fn current_path(&self, _: &Arc<dyn Fs>) -> Result<PathBuf> {\n        let fd = self.as_fd();\n        let fd_path = format!(\"/proc/self/fd/{}\", fd.as_raw_fd());\n        let new_path = std::fs::read_link(fd_path)?;\n        if new_path\n            .file_name()\n            .is_some_and(|f| f.to_string_lossy().ends_with(\" (deleted)\"))\n        {\n            anyhow::bail!(\"file was deleted\")\n        };\n\n        Ok(new_path)\n    }\n\n    #[cfg(target_os = \"freebsd\")]\n    fn current_path(&self, _: &Arc<dyn Fs>) -> Result<PathBuf> {\n        use std::{\n            ffi::{CStr, OsStr},\n            os::unix::ffi::OsStrExt,\n        };\n\n        let fd = self.as_fd();\n        let mut kif = MaybeUninit::<libc::kinfo_file>::uninit();\n        kif.kf_structsize = libc::KINFO_FILE_SIZE;\n\n        let result = unsafe { libc::fcntl(fd.as_raw_fd(), libc::F_KINFO, kif.as_mut_ptr()) };\n        anyhow::ensure!(result != -1, \"fcntl returned -1\");","sourceCodeStart":478,"sourceCodeEnd":514,"githubUrl":"https://github.com/zed-industries/zed/blob/9d272b036335401f339d024ea94968fd51016c40/crates/fs/src/fs.rs#L478-L514","documentation":"On Linux, Fs::current_path for an open file resolves /proc/self/fd/<fd> via readlink. When the kernel has unlinked the file but the descriptor is still open, the symlink target carries the literal suffix \" (deleted)\"; the implementation detects that suffix and bails with \"file was deleted\" instead of returning a bogus path. This is Linux's standard way of exposing an open-but-unlinked file.","triggerScenarios":"Calling current_path on a File whose backing path was deleted or replaced while open — editors writing via rename-over, build systems removing outputs, log rotation, or a git operation rewriting the worktree.","commonSituations":"A worktree file is deleted/replaced by git checkout/clean while the editor holds it open; files under /tmp cleaned by a tmpwatcher; two processes racing where one renames over the other's open file.","solutions":["Treat the error as authoritative: the original path no longer exists; re-open by a known path or drop the stale handle","Restore/recreate the file at its original path if the caller still needs it there","Avoid rename-over patterns when other processes hold the path open, or coordinate the replacement"],"exampleFix":"// before\nlet path = file.current_path(&fs).await?;\n\n// after\nlet path = match file.current_path(&fs).await {\n    Ok(path) => path,\n    Err(e) if e.to_string().contains(\"file was deleted\") => {\n        // descriptor is open but unlinked; re-resolve from a known path\n        known_path.clone()\n    }\n    Err(e) => return Err(e.into()),\n};","handlingStrategy":"try-catch","validationCode":"// liveness check before relying on the descriptor's path\nlet meta = fs.metadata(&known_path).await;\nif meta.is_err() {\n    // path already gone; don't ask current_path for it\n}","typeGuard":null,"tryCatchPattern":"let path = match file.current_path(&fs).await {\n    Ok(path) => path,\n    Err(e) if e.to_string().contains(\"file was deleted\") => { /* re-open from known path */ }\n    Err(e) => return Err(e.into()),\n};","preventionTips":["Keep a known-path copy instead of re-deriving paths from live descriptors","Expect rename-over writes (editors, log rotation) to invalidate open-file paths on Linux"],"tags":["filesystem","linux","procfs","deleted-file","file-handle"],"backgroundTag":"stale-file-handle","analyzedSha":"9d272b036335401f339d024ea94968fd51016c40","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}