{"record":{"id":"ab978e79a03e299c","repo":"sxyazi/yazi","slug":"not-a-local-url","errorCode":null,"errorMessage":"Not a local URL: {:?}","messagePattern":"Not a local URL: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/engine/local/local.rs","lineNumber":104,"sourceCode":"\t#[inline]\n\tasync fn new<'b>(url: Url<'b>) -> io::Result<Self::Me<'b>> {\n\t\tmatch url {\n\t\t\tUrl::Regular(loc) | Url::Search { loc, .. } => Ok(Self::Me { url, path: loc.as_inner() }),\n\t\t\tUrl::Mount { .. } | Url::Hub { .. } | Url::Scope { .. } | Url::Sftp { .. } => {\n\t\t\t\tErr(io::Error::new(io::ErrorKind::InvalidInput, format!(\"Not a local URL: {url:?}\")))\n\t\t\t}\n\t\t}\n\t}\n\n\t#[inline]\n\tasync fn read_dir(self) -> io::Result<Self::ReadDir> {\n\t\tOk(match self.url.kind() {\n\t\t\tAuthKind::Regular => Self::ReadDir::Regular(tokio::fs::read_dir(self.path).await?),\n\t\t\tAuthKind::Search => Self::ReadDir::Others {\n\t\t\t\treader: tokio::fs::read_dir(self.path).await?,\n\t\t\t\tdir:    Arc::new(self.url.to_owned()),\n\t\t\t},\n\t\t\tAuthKind::Mount | AuthKind::Hub | AuthKind::Scope | AuthKind::Sftp => Err(io::Error::new(\n\t\t\t\tio::ErrorKind::InvalidInput,\n\t\t\t\tformat!(\"Not a local URL: {:?}\", self.url),\n\t\t\t))?,\n\t\t})\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\n\t#[inline]\n\tasync fn remove_dir_all(&self) -> io::Result<()> { tokio::fs::remove_dir_all(self.path).await }\n\n\t#[inline]","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-fs/src/engine/local/local.rs#L86-L122","documentation":"`Local::read_dir` (local.rs:104) dispatches on `self.url.kind()`: `Regular` and `Search` are listed via `tokio::fs::read_dir`, but `Mount | Hub | Scope | Sftp` kinds return `InvalidInput` with `Not a local URL: {:?}`. This is reachable because a `Url::Search` can carry a location whose kind is non-local (e.g. a search rooted inside an archive mount), even though `Local::new` accepted it.","triggerScenarios":"Constructing `Local` from a `Url::Search` whose underlying location is a mount/hub/sftp URL, then calling `read_dir()`; or re-kindling a URL that changed kind between construction and the `read_dir` call.","commonSituations":"Searching inside an archived or remote directory and then trying to enumerate the results through the local engine; plugins that rewrap search URLs of remote roots into local handles.","solutions":["Before `read_dir`, check `url.kind()` and route non-Regular/Search kinds to the owning backend.","When creating search URLs over remote/mounted roots, enumerate through that root's engine rather than the local one.","Log the full URL (`{:?}` of `self.url`) at the failure site to identify which kind leaked through."],"exampleFix":"// before\nlet entries = local.read_dir().await?; // InvalidInput if kind is Mount/Sftp\n\n// after\nuse yazi_fs::engine::AuthKind;\nmatch local.url().kind() {\n    AuthKind::Regular | AuthKind::Search => { let entries = local.read_dir().await?; }\n    kind => { /* delegate to the engine registered for `kind` */ }\n}","handlingStrategy":"validation","validationCode":"use yazi_fs::engine::AuthKind;\n\nmatch local.url().kind() {\n    AuthKind::Regular | AuthKind::Search => { /* safe to read_dir */ }\n    kind => { /* delegate listing to the engine owning `kind` */ }\n}","typeGuard":"fn is_listable_locally(kind: AuthKind) -> bool {\n    matches!(kind, AuthKind::Regular | AuthKind::Search)\n}","tryCatchPattern":"match local.read_dir().await {\n    Ok(rd) => { /* ... */ }\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput => { /* non-local kind leaked in: log url {:?} and re-dispatch */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Check the URL kind immediately before read_dir, not just at construction time.","For searches over remote/mounted roots, enumerate through that root's engine.","Log the offending URL when this fires so the leaking producer can be fixed."],"tags":["url","read-dir","local-engine","search","input-validation"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}