{"record":{"id":"72dfd2e0a9dedd1b","repo":"rustdesk/rustdesk","slug":"file-handle-not-found","errorCode":null,"errorMessage":"file handle not found","messagePattern":"file handle not found","errorType":"exception","errorClass":"CliprdrError","httpStatus":null,"severity":"error","filePath":"libs/clipboard/src/platform/unix/local_file.rs","lineNumber":230,"sourceCode":"                err: e,\n            })?;\n            let mut reader = BufReader::with_capacity(BLOCK_SIZE as usize * 2, handle);\n            reader.fill_buf().map_err(|e| CliprdrError::FileError {\n                path: self.path.to_string_lossy().to_string(),\n                err: e,\n            })?;\n            self.handle = Some(reader);\n        };\n        Ok(())\n    }\n\n    pub fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> Result<(), CliprdrError> {\n        self.load_handle()?;\n\n        let Some(handle) = self.handle.as_mut() else {\n            return Err(CliprdrError::FileError {\n                path: self.path.to_string_lossy().to_string(),\n                err: std::io::Error::new(std::io::ErrorKind::NotFound, \"file handle not found\"),\n            });\n        };\n\n        let read_result = if offset != self.offset.load(Ordering::Relaxed) {\n            handle\n                .seek(std::io::SeekFrom::Start(offset))\n                .and_then(|_| handle.read_exact(buf))\n        } else {\n            handle.read_exact(buf)\n        };\n        if let Err(e) = read_result {\n            return Err(self.invalidate_handle(e));\n        }\n        let new_offset = offset + (buf.len() as u64);\n        self.offset.store(new_offset, Ordering::Relaxed);\n\n        // gc file handle\n        if new_offset >= self.size {","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/libs/clipboard/src/platform/unix/local_file.rs#L212-L248","documentation":"LocalFile::read_exact_at first calls load_handle() to (re)open the backing file, then expects self.handle to be Some. If after load_handle the handle is still None, it cannot satisfy the positional read and returns CliprdrError::FileError wrapping io::ErrorKind::NotFound with 'file handle not found' for the file's path.","triggerScenarios":"Calling read_exact_at on a LocalFile whose load_handle() succeeded but left self.handle unset — i.e. the underlying open path produced no handle, or the handle was cleared concurrently/between calls and load_handle did not re-open it.","commonSituations":"Reading a clipboard file that was deleted or became inaccessible between listing and download; the file being a special file that opens differently; a race where close/release runs while a read is in flight.","solutions":["Check the file still exists and is a regular file before starting the transfer","Call load_handle()/open explicitly and verify it returns a handle before reading","Retry the operation after re-creating the LocalFile for the path","Verify the path is valid on the local side (not a stale remote descriptor)"],"exampleFix":"// before\nself.load_handle()?;\n// after: fail early if handle could not be established\nself.load_handle()?;\nif self.handle.is_none() {\n    return Err(CliprdrError::FileError {\n        path: self.path.to_string_lossy().to_string(),\n        err: std::io::Error::new(std::io::ErrorKind::NotFound, \"file handle not found\"),\n    });\n}","handlingStrategy":"validation","validationCode":"// before transferring, verify the local file is readable\nlet p = std::path::Path::new(&path);\nif !p.is_file() {\n    return Err(anyhow!(\"file missing before transfer: {}\", path));\n}","typeGuard":null,"tryCatchPattern":"match file.read_exact_at(&mut buf, offset) {\n    Ok(()) => {},\n    Err(CliprdrError::FileError { path, err }) if err.kind() == std::io::ErrorKind::NotFound => {\n        // re-create LocalFile for `path` and retry once\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Re-verify the file exists after listing and before download","Call load_handle() explicitly and check handle presence before reads","Avoid concurrent close/read on the same LocalFile"],"tags":["file-io","clipboard","not-found","handle"],"backgroundTag":"file-not-found","analyzedSha":"91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540","analyzedAt":"2026-09-10T19:53:44.083Z","contentChangedAt":"2026-09-10T19:53:44.083Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}