{"record":{"id":"8130c8622eb2dc14","repo":"sxyazi/yazi","slug":"not-a-local-url-url-8130c8","errorCode":null,"errorMessage":"Not a local URL: {url}","messagePattern":"Not a local URL: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/engine/local/local.rs","lineNumber":75,"sourceCode":"\t#[inline]\n\tasync fn hard_link<P>(&self, to: P) -> io::Result<()>\n\twhere\n\t\tP: DynPath,\n\t{\n\t\tlet to = to.dyn_path().as_os()?;\n\n\t\ttokio::fs::hard_link(self.path, to).await\n\t}\n\n\t#[inline]\n\tasync fn metadata(&self) -> io::Result<Cha> {\n\t\tOk(Cha::new(self.path.file_name().unwrap_or_default(), tokio::fs::metadata(self.path).await?))\n\t}\n\n\t#[inline]\n\tasync fn new<'b>(url: Url<'b>) -> io::Result<Self::Me<'b>> {\n\t\tlet path = url.as_local().ok_or_else(|| {\n\t\t\tio::Error::new(io::ErrorKind::InvalidInput, format!(\"Not a local URL: {url}\"))\n\t\t})?;\n\n\t\tOk(Self::Me { url, path })\n\t}\n\n\t#[inline]\n\tasync fn read_dir(self) -> io::Result<Self::ReadDir> {\n\t\tOk(super::ReadDir(tokio::fs::read_dir(self.path).await?))\n\t}\n\n\t#[inline]\n\tasync fn read_link(&self) -> io::Result<PathBufDyn> {\n\t\tOk(tokio::fs::read_link(self.path).await?.into())\n\t}\n\n\t#[inline]\n\tasync fn remove_dir(&self) -> io::Result<()> { tokio::fs::remove_dir(self.path).await }\n","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-fs/src/engine/local/local.rs#L57-L93","documentation":"LocalFs::new constructs a local filesystem entry from a URL, but only if `url.as_local()` yields a path. Non-local (e.g. SFTP) URLs are rejected with an InvalidInput error. It is the constructor-level equivalent of the open-time check in the local engine.","triggerScenarios":"Creating a LocalFs entry (File/Folder via `new`) with a remote or otherwise non-local Url, such as a Unix URL carrying SFTP auth.","commonSituations":"Generic code that dispatches on URL kind but falls through to LocalFs for unknown schemes; copied code that assumed all URLs in a tab are local; hover/preview logic given a remote entry.","solutions":["Dispatch on the URL scheme first: only build LocalFs entries for local URLs; use Vfs/Sftp for remote ones.","If the URL should be local, strip the remote auth / construct it with `Url::from` on a real filesystem path.","Add an `url.as_local().is_some()` guard before calling the constructor."],"exampleFix":"// before\nlet file = LocalFs::File::new(url).await?;\n// after\nensure!(url.as_local().is_some(), \"use Vfs for remote URLs\");\nlet file = LocalFs::File::new(url).await?;","handlingStrategy":"type-guard","validationCode":"if url.as_local().is_none() { bail!(\"LocalFs::new requires a local URL\"); }","typeGuard":"fn is_local(url: &Url) -> bool { url.as_local().is_some() }","tryCatchPattern":"// io::Error with InvalidInput kind\nmatch LocalFs::File::new(url).await {\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput => return Vfs::entry(url).await,\n    other => other.map_err(Into::into),\n}","preventionTips":["Dispatch on URL scheme before choosing a filesystem engine.","Never treat unknown schemes as local by default.","Add unit checks that LocalFs is only constructed from path-backed URLs."],"tags":["io","url","filesystem","rust"],"backgroundTag":"invalid-url","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-09T22:26:16.379Z","contentChangedAt":"2026-09-09T22:26:16.379Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}