{"record":{"id":"b9b7b85dc44747cc","repo":"sxyazi/yazi","slug":"uri-exceeds-the-entire-url","errorCode":null,"errorMessage":"URI exceeds the entire URL","messagePattern":"URI exceeds the entire URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"yazi-shared/src/loc/loc.rs","lineNumber":225,"sourceCode":"\twhere\n\t\tT: PathView<'p, P>,\n\t{\n\t\tif urn > uri {\n\t\t\tbail!(\"URN cannot be longer than URI\");\n\t\t}\n\n\t\tlet mut loc = Self::bare(path);\n\t\tif uri == 0 {\n\t\t\t(loc.uri, loc.urn) = (0, 0);\n\t\t\treturn Ok(loc);\n\t\t} else if urn == 0 {\n\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","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-shared/src/loc/loc.rs#L207-L243","documentation":"`Loc::with` walks the path's components backwards `uri` times to compute the URI prefix boundary. If the URL has fewer components than the requested `uri` count, the iterator is exhausted and it bails with \"URI exceeds the entire URL\". The URI count must not exceed the actual number of components in the path.","triggerScenarios":"Calling `Loc::with(path, uri, urn)` where `uri` is larger than the number of components in `path.inner` — e.g. `with(\"/a/b.txt\", 5, 1)` on a path with only two components; counts computed from a different (deeper) path then applied to a shallower one.","commonSituations":"Hover/parent logic that carries a component count from a child URL to a shortened parent URL; cache-keyed Loc state reused across URL changes in a preview or tab switch; off-by-one counting that includes the root as a component.","solutions":["Clamp `uri` to the path's actual component count before calling `with`.","Recompute the count from the exact same URL passed to `with`, not a stale one.","Treat root (`/`) as not countable the same way as named components when deriving counts.","On version upgrades, re-derive Loc state instead of reusing cached (uri, urn) counters across URLs."],"exampleFix":"// before\nlet loc = Loc::with(shortened_url, old_count, urn_count)?; // old_count from a deeper path\n// after\nlet count = old_count.min(shortened_url.components().count());\nlet loc = Loc::with(shortened_url, count, urn_count.min(count))?;","handlingStrategy":"validation","validationCode":"fn clamp_uri(url: &Url, uri: usize) -> usize {\n    uri.min(url.components().count())\n}","typeGuard":null,"tryCatchPattern":"let count = stale_count.min(url.components().count());\nlet loc = Loc::with(url, count, urn_count.min(count))?;","preventionTips":["Never reuse (uri, urn) counts across different URLs; recompute per path.","Clamp counts to the path's component count before calling with().","Recalculate Loc state after tab/preview URL changes.","Remember the root component is not a normal component when counting."],"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-14T00:17:10.932Z"}