{"record":{"id":"797daf9c1447bec0","repo":"gitui-org/gitui","slug":"invalid-path-797daf","errorCode":null,"errorMessage":"invalid path","messagePattern":"invalid path","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/components/utils/filetree.rs","lineNumber":213,"sourceCode":"\t\tparent_index\n\t}\n\n\tfn push_dirs<'a>(\n\t\titem_path: &'a Path,\n\t\tnodes: &mut Vec<FileTreeItem>,\n\t\tpaths_added: &mut BTreeSet<&'a Path>,\n\t\tcollapsed: &BTreeSet<&String>,\n\t) -> Result<()> {\n\t\tlet mut ancestors =\n\t\t\t{ item_path.ancestors().skip(1).collect::<Vec<_>>() };\n\t\tancestors.reverse();\n\n\t\tfor c in &ancestors {\n\t\t\tif c.parent().is_some() && !paths_added.contains(c) {\n\t\t\t\tpaths_added.insert(c);\n\t\t\t\t//TODO: get rid of expect\n\t\t\t\tlet path_string =\n\t\t\t\t\tString::from(c.to_str().expect(\"invalid path\"));\n\t\t\t\tlet is_collapsed = collapsed.contains(&path_string);\n\t\t\t\tnodes.push(FileTreeItem::new_path(\n\t\t\t\t\tc,\n\t\t\t\t\tpath_string,\n\t\t\t\t\tis_collapsed,\n\t\t\t\t)?);\n\t\t\t}\n\t\t}\n\n\t\tOk(())\n\t}\n\n\tpub fn multiple_items_at_path(&self, index: usize) -> bool {\n\t\tlet tree_items = self.items();\n\t\tlet mut idx_temp_inner;\n\t\tif index + 2 < tree_items.len() {\n\t\t\tidx_temp_inner = index + 1;\n\t\t\twhile idx_temp_inner < tree_items.len().saturating_sub(1)","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/gitui-org/gitui/blob/2fa693cb6ed431b21ebc300dd02e83c2476699ce/src/components/utils/filetree.rs#L195-L231","documentation":"Building the collapsed/expanded file tree inserts directory ancestors for every changed path. Path::to_str() returns None when the path is not valid UTF-8, and the expect() (which carries a TODO to remove it) turns that into a panic while constructing the tree - the file/status view cannot render. Same input class as the status-tree panic, hit through the tree builder.","triggerScenarios":"Any changed or untracked path whose bytes are invalid UTF-8, including parent directory names since ancestors are walked and inserted as nodes.","commonSituations":"Repos containing latin-1 or Shift-JIS named directories; files extracted from archives with mangled names; cross-platform checkouts that materialized unusual paths.","solutions":["Detect and rename offending paths: git -c core.quotepath=false ls-files | LC_ALL=C grep -n '[^ -~]', plus untracked files via git status --porcelain -uall.","git mv the tracked offenders to UTF-8 names and delete/rename untracked ones.","Update gitui - this expect is a known TODO that was reworked; report with the path bytes if it still reproduces."],"exampleFix":"// before\nlet path_string = String::from(c.to_str().expect(\"invalid path\"));\n// after: skip or placeholder non-UTF-8 entries\nlet path_string = c.to_str().unwrap_or(\"(non-utf8 path)\").to_string();","handlingStrategy":"validation","validationCode":"# detect non-UTF-8 paths before launching into the tree view\ngit -c core.quotepath=false ls-files | LC_ALL=C grep -n '[^ -~]'\ngit -c core.quotepath=false status --porcelain --untracked-files=all | LC_ALL=C grep -n '[^ -~]'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enforce UTF-8 filenames in repos you manage (lint in CI).","Prefer to_string_lossy() or to_str().unwrap_or(fallback) when converting paths for UI text.","Track upstream hardening of the file-tree module; the TODO marks it as known debt."],"tags":["panic","non-utf8","file-tree","path","todo"],"backgroundTag":"non-utf8-file-path","analyzedSha":"2fa693cb6ed431b21ebc300dd02e83c2476699ce","analyzedAt":"2026-08-16T23:07:36.562Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}