{"record":{"id":"76d71d31b9a7b23f","repo":"sxyazi/yazi","slug":"urn-cannot-include-a-root-directory","errorCode":null,"errorMessage":"URN cannot include a root directory","messagePattern":"URN cannot include a root directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"yazi-shared/src/loc/loc.rs","lineNumber":237,"sourceCode":"\t\t\tloc.urn = 0;\n\t\t}\n\n\t\tlet mut it = loc.inner.components();\n\t\tfor i in 1..=uri {\n\t\t\tif it.next_back().is_none() {\n\t\t\t\tbail!(\"URI exceeds the entire URL\");\n\t\t\t}\n\t\t\tif i == urn {\n\t\t\t\tloc.urn = loc.strip_prefix(it.clone()).unwrap().len();\n\t\t\t}\n\t\t\tif i == uri {\n\t\t\t\tloc.uri = loc.strip_prefix(it).unwrap().len();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif loc.urn().has_root() {\n\t\t\tbail!(\"URN cannot include a root directory\");\n\t\t}\n\t\tOk(loc)\n\t}\n\n\tpub(crate) fn zeroed<T>(path: T) -> Self\n\twhere\n\t\tT: PathView<'p, P>,\n\t{\n\t\tlet mut loc = Self::bare(path);\n\t\t(loc.uri, loc.urn) = (0, 0);\n\t\tloc\n\t}\n}\n\n#[cfg(test)]\nmod tests {\n\tuse std::path::Path;\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-shared/src/loc/loc.rs#L219-L255","documentation":"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\".","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet loc = Loc::with(url, comps, comps)?; // comps includes root -> URN is \"/...\"\n// after\nlet comps = url.components().count();\nlet usable = if url.has_root() { comps - 1 } else { comps };\nlet loc = Loc::with(url, usable.max(1), usable.min(usable))?;","handlingStrategy":"validation","validationCode":"fn usable_components(url: &Url) -> usize {\n    let n = url.components().count();\n    if url.components().has_root() { n - 1 } else { n }\n}","typeGuard":null,"tryCatchPattern":"let n = usable_components(&url);\nlet loc = if n == 0 { Loc::zeroed(&url) } else { Loc::with(&url, n, n)? };","preventionTips":["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."],"tags":["rust","url","invariant","yazi-shared"],"backgroundTag":"invalid-path-component-count","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}