sxyazi/yazi · critical
URN cannot include a root directory
Error message
URN cannot include a root directory
What it means
After computing the URI/URN boundaries, `Loc::with` verifies that the resulting URN (the file-name tail slice) does not contain a root directory component. A URN is meant to be the final, relative name portion of the URL; if the requested urn/uri counts pull in the filesystem root (e.g. on a path whose whole body was consumed), it bails with "URN cannot include a root directory".
Source
Thrown at yazi-shared/src/loc/loc.rs:237
loc.urn = 0;
}
let mut it = loc.inner.components();
for i in 1..=uri {
if it.next_back().is_none() {
bail!("URI exceeds the entire URL");
}
if i == urn {
loc.urn = loc.strip_prefix(it.clone()).unwrap().len();
}
if i == uri {
loc.uri = loc.strip_prefix(it).unwrap().len();
break;
}
}
if loc.urn().has_root() {
bail!("URN cannot include a root directory");
}
Ok(loc)
}
pub(crate) fn zeroed<T>(path: T) -> Self
where
T: PathView<'p, P>,
{
let mut loc = Self::bare(path);
(loc.uri, loc.urn) = (0, 0);
loc
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
View on GitHub (pinned to 8ebf930f17)
Solutions
- Reduce the urn (and uri) counts so the URN tail stops below the root component.
- Exclude the root when counting components for urn/uri derivation.
- Use `Loc::zeroed` or the bare constructor when you want no urn/uri split for near-root paths.
- Guard the call: if the path's component count equals the desired urn count on an absolute path, decrement or zero it.
Example fix
// before
let loc = Loc::with(url, comps, comps)?; // comps includes root -> URN is "/..."
// after
let comps = url.components().count();
let usable = if url.has_root() { comps - 1 } else { comps };
let loc = Loc::with(url, usable.max(1), usable.min(usable))?; Defensive patterns
Strategy: validation
Validate before calling
fn usable_components(url: &Url) -> usize {
let n = url.components().count();
if url.components().has_root() { n - 1 } else { n }
} Try / catch
let n = usable_components(&url);
let loc = if n == 0 { Loc::zeroed(&url) } else { Loc::with(&url, n, n)? }; Prevention
- Exclude the root from component counts on absolute paths.
- Use Loc::zeroed/bare for paths at or near the filesystem root.
- Guard against counts that would make urn() start at '/'.
- Test hover/spot logic on root-level files (e.g. /file) where exhaustion happens sooner.
When it happens
Trigger: Calling `Loc::with` with component counts large enough that the URN slice begins at the path root — e.g. urn counts covering all components of `/file` so `loc.urn()` starts at `/`; applying deep-path counts to a path one component short of exhausting to the root.
Common situations: Computing urn/uri counts on absolute paths without excluding the root component; passing a count from a path like `/a/b/c` to a path like `/a`; hover or spot code that walks to the topmost ancestor of a root-level file.
Related errors
- URN cannot be longer than URI
- URI exceeds the entire URL
- not a URL
- not a number
- argument not found: {:?}
AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02).
Data as JSON: /api/errors/76d71d31b9a7b23f.
Report an issue: GitHub.